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.c4085
1 files changed, 0 insertions, 4085 deletions
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
deleted file mode 100644
index faacb3aab..000000000
--- a/src/transport/gnunet-communicator-tcp.c
+++ /dev/null
@@ -1,4085 +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). Currently 400 MB
86 */
87#define REKEY_MAX_BYTES (1024LLU * 1024 * 400)
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 * ID of read task for this connection.
473 */
474 struct GNUNET_SCHEDULER_Task *read_task;
475
476 /**
477 * ID of write task for this connection.
478 */
479 struct GNUNET_SCHEDULER_Task *write_task;
480
481 /**
482 * Address of the other peer.
483 */
484 struct sockaddr *address;
485
486 /**
487 * How many more bytes may we sent with the current @e out_cipher
488 * before we should rekey?
489 */
490 uint64_t rekey_left_bytes;
491
492 /**
493 * Until what time may we sent with the current @e out_cipher
494 * before we should rekey?
495 */
496 struct GNUNET_TIME_Absolute rekey_time;
497
498 /**
499 * Length of the address.
500 */
501 socklen_t address_len;
502
503 /**
504 * Message queue we are providing for the #ch.
505 */
506 struct GNUNET_MQ_Handle *mq;
507
508 /**
509 * handle for this queue with the #ch.
510 */
511 struct GNUNET_TRANSPORT_QueueHandle *qh;
512
513 /**
514 * Number of bytes we currently have in our write queue.
515 */
516 unsigned long long bytes_in_queue;
517
518 /**
519 * Buffer for reading ciphertext from network into.
520 */
521 char cread_buf[BUF_SIZE];
522
523 /**
524 * buffer for writing ciphertext to network.
525 */
526 char cwrite_buf[BUF_SIZE];
527
528 /**
529 * Plaintext buffer for decrypted plaintext.
530 */
531 char pread_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
532
533 /**
534 * Plaintext buffer for messages to be encrypted.
535 */
536 char pwrite_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
537
538 /**
539 * At which offset in the ciphertext read buffer should we
540 * append more ciphertext for transmission next?
541 */
542 size_t cread_off;
543
544 /**
545 * At which offset in the ciphertext write buffer should we
546 * append more ciphertext from reading next?
547 */
548 size_t cwrite_off;
549
550 /**
551 * At which offset in the plaintext input buffer should we
552 * append more plaintext from decryption next?
553 */
554 size_t pread_off;
555
556 /**
557 * At which offset in the plaintext output buffer should we
558 * append more plaintext for encryption next?
559 */
560 size_t pwrite_off;
561
562 /**
563 * Timeout for this queue.
564 */
565 struct GNUNET_TIME_Absolute timeout;
566
567 /**
568 * How may messages did we pass from this queue to CORE for which we
569 * have yet to receive an acknoweldgement that CORE is done with
570 * them? If "large" (or even just non-zero), we should throttle
571 * reading to provide flow control. See also #DEFAULT_MAX_QUEUE_LENGTH
572 * and #max_queue_length.
573 */
574 unsigned int backpressure;
575
576 /**
577 * Which network type does this queue use?
578 */
579 enum GNUNET_NetworkType nt;
580
581 /**
582 * The connection status of this queue.
583 */
584 enum GNUNET_TRANSPORT_ConnectionStatus cs;
585
586 /**
587 * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call?
588 */
589 int mq_awaits_continue;
590
591 /**
592 * Did we enqueue a finish message and are closing down the queue?
593 */
594 int finishing;
595
596 /**
597 * Did we technically destroy this queue, but kept the allocation
598 * around because of @e backpressure not being zero yet? Used
599 * simply to delay the final #GNUNET_free() operation until
600 * #core_read_finished_cb() has been called.
601 */
602 int destroyed;
603
604 /**
605 * #GNUNET_YES if we just rekeyed and must thus possibly
606 * re-decrypt ciphertext.
607 */
608 int rekeyed;
609
610 /**
611 * Monotonic time value for rekey message.
612 */
613 struct GNUNET_TIME_AbsoluteNBO rekey_monotonic_time;
614
615 /**
616 * Monotonic time value for handshake message.
617 */
618 struct GNUNET_TIME_AbsoluteNBO handshake_monotonic_time;
619
620 /**
621 * Monotonic time value for handshake ack message.
622 */
623 struct GNUNET_TIME_AbsoluteNBO handshake_ack_monotonic_time;
624
625 /**
626 * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
627 */
628 struct GNUNET_CRYPTO_ChallengeNonceP challenge;
629
630 /**
631 * 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.
632 */
633 struct GNUNET_CRYPTO_ChallengeNonceP challenge_received;
634
635 /**
636 * Iteration Context for retrieving the monotonic time send with key for rekeying.
637 */
638 struct GNUNET_PEERSTORE_IterateContext *rekey_monotime_get;
639
640 /**
641 * Iteration Context for retrieving the monotonic time send with the handshake.
642 */
643 struct GNUNET_PEERSTORE_IterateContext *handshake_monotime_get;
644
645 /**
646 * Iteration Context for retrieving the monotonic time send with the handshake ack.
647 */
648 struct GNUNET_PEERSTORE_IterateContext *handshake_ack_monotime_get;
649
650 /**
651 * Store Context for retrieving the monotonic time send with key for rekeying.
652 */
653 struct GNUNET_PEERSTORE_StoreContext *rekey_monotime_sc;
654
655 /**
656 * Store Context for retrieving the monotonic time send with the handshake.
657 */
658 struct GNUNET_PEERSTORE_StoreContext *handshake_monotime_sc;
659
660 /**
661 * Store Context for retrieving the monotonic time send with the handshake ack.
662 */
663 struct GNUNET_PEERSTORE_StoreContext *handshake_ack_monotime_sc;
664
665 /**
666 * Size of data received without KX challenge played back.
667 */
668 // TODO remove?
669 size_t unverified_size;
670
671 /**
672 * Has the initial (core) handshake already happened?
673 */
674 int initial_core_kx_done;
675};
676
677
678/**
679 * Handle for an incoming connection where we do not yet have enough
680 * information to setup a full queue.
681 */
682struct ProtoQueue
683{
684 /**
685 * Kept in a DLL.
686 */
687 struct ProtoQueue *next;
688
689 /**
690 * Kept in a DLL.
691 */
692 struct ProtoQueue *prev;
693
694 /**
695 * Listen socket.
696 */
697 struct GNUNET_NETWORK_Handle *listen_sock;
698
699 /**
700 * socket that we transmit all data with on this queue
701 */
702 struct GNUNET_NETWORK_Handle *sock;
703
704 /**
705 * ID of write task for this connection.
706 */
707 struct GNUNET_SCHEDULER_Task *write_task;
708
709 /**
710 * buffer for writing struct TCPNATProbeMessage to network.
711 */
712 char write_buf[sizeof (struct TCPNATProbeMessage)];
713
714 /**
715 * Offset of the buffer?
716 */
717 size_t write_off;
718
719 /**
720 * ID of read task for this connection.
721 */
722 struct GNUNET_SCHEDULER_Task *read_task;
723
724 /**
725 * Address of the other peer.
726 */
727 struct sockaddr *address;
728
729 /**
730 * Length of the address.
731 */
732 socklen_t address_len;
733
734 /**
735 * Timeout for this protoqueue.
736 */
737 struct GNUNET_TIME_Absolute timeout;
738
739 /**
740 * Buffer for reading all the information we need to upgrade from
741 * protoqueue to queue.
742 */
743 char ibuf[INITIAL_KX_SIZE];
744
745 /**
746 * Current offset for reading into @e ibuf.
747 */
748 size_t ibuf_off;
749};
750
751/**
752 * In case of port only configuration we like to bind to ipv4 and ipv6 addresses.
753 */
754struct PortOnlyIpv4Ipv6
755{
756 /**
757 * Ipv4 address we like to bind to.
758 */
759 struct sockaddr *addr_ipv4;
760
761 /**
762 * Length of ipv4 address.
763 */
764 socklen_t addr_len_ipv4;
765
766 /**
767 * Ipv6 address we like to bind to.
768 */
769 struct sockaddr *addr_ipv6;
770
771 /**
772 * Length of ipv6 address.
773 */
774 socklen_t addr_len_ipv6;
775
776};
777
778/**
779 * DLL to store the addresses we like to register at NAT service.
780 */
781struct Addresses
782{
783 /**
784 * Kept in a DLL.
785 */
786 struct Addresses *next;
787
788 /**
789 * Kept in a DLL.
790 */
791 struct Addresses *prev;
792
793 /**
794 * Address we like to register at NAT service.
795 */
796 struct sockaddr *addr;
797
798 /**
799 * Length of address we like to register at NAT service.
800 */
801 socklen_t addr_len;
802
803};
804
805
806/**
807 * Maximum queue length before we stop reading towards the transport service.
808 */
809static unsigned long long max_queue_length;
810
811/**
812 * For logging statistics.
813 */
814static struct GNUNET_STATISTICS_Handle *stats;
815
816/**
817 * Our environment.
818 */
819static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
820
821/**
822 * Queues (map from peer identity to `struct Queue`)
823 */
824static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
825
826/**
827 * ListenTasks (map from socket to `struct ListenTask`)
828 */
829static struct GNUNET_CONTAINER_MultiHashMap *lt_map;
830
831/**
832 * Our public key.
833 */
834static struct GNUNET_PeerIdentity my_identity;
835
836/**
837 * The rekey interval
838 */
839static struct GNUNET_TIME_Relative rekey_interval;
840
841/**
842 * Our private key.
843 */
844static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
845
846/**
847 * Our configuration.
848 */
849static const struct GNUNET_CONFIGURATION_Handle *cfg;
850
851/**
852 * Network scanner to determine network types.
853 */
854static struct GNUNET_NT_InterfaceScanner *is;
855
856/**
857 * Connection to NAT service.
858 */
859static struct GNUNET_NAT_Handle *nat;
860
861/**
862 * Protoqueues DLL head.
863 */
864static struct ProtoQueue *proto_head;
865
866/**
867 * Protoqueues DLL tail.
868 */
869static struct ProtoQueue *proto_tail;
870
871/**
872 * Handle for DNS lookup of bindto address
873 */
874struct GNUNET_RESOLVER_RequestHandle *resolve_request_handle;
875
876/**
877 * Head of DLL with addresses we like to register at NAT servcie.
878 */
879struct Addresses *addrs_head;
880
881/**
882 * Head of DLL with addresses we like to register at NAT servcie.
883 */
884struct Addresses *addrs_tail;
885
886/**
887 * Head of DLL with ListenTasks.
888 */
889struct ListenTask *lts_head;
890
891/**
892 * Head of DLL with ListenTask.
893 */
894struct ListenTask *lts_tail;
895
896/**
897 * Number of addresses in the DLL for register at NAT service.
898 */
899int addrs_lens;
900
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 k;
1361
1362 GNUNET_CRYPTO_eddsa_kem_decaps (my_private_key, ephemeral, &k);
1363 setup_cipher (&k, &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, struct GNUNET_HashCode *dh)
1561{
1562 setup_cipher (dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1563 queue->rekey_time = GNUNET_TIME_relative_to_absolute (rekey_interval);
1564 queue->rekey_left_bytes =
1565 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, REKEY_MAX_BYTES);
1566}
1567
1568
1569/**
1570 * Inject a `struct TCPRekey` message into the queue's plaintext
1571 * buffer.
1572 *
1573 * @param queue queue to perform rekeying on
1574 */
1575static void
1576inject_rekey (struct Queue *queue)
1577{
1578 struct TCPRekey rekey;
1579 struct TcpRekeySignature thp;
1580 struct GNUNET_HashCode k;
1581 struct GNUNET_CRYPTO_EcdhePublicKey c;
1582
1583 GNUNET_assert (0 == queue->pwrite_off);
1584 memset (&rekey, 0, sizeof(rekey));
1585 GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &rekey.ephemeral,
1586 &k);
1587 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1588 rekey.header.size = ntohs (sizeof(rekey));
1589 rekey.monotonic_time =
1590 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1591 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY);
1592 thp.purpose.size = htonl (sizeof(thp));
1593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1594 "inject_rekey size %u\n",
1595 thp.purpose.size);
1596 thp.sender = my_identity;
1597 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1598 "sender %s\n",
1599 GNUNET_p2s (&thp.sender.public_key));
1600 thp.receiver = queue->target;
1601 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1602 "receiver %s\n",
1603 GNUNET_p2s (&thp.receiver.public_key));
1604 thp.ephemeral = rekey.ephemeral;
1605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1606 "ephemeral %s\n",
1607 GNUNET_e2s (&thp.ephemeral));
1608 thp.monotonic_time = rekey.monotonic_time;
1609 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1610 "time %s\n",
1611 GNUNET_STRINGS_absolute_time_to_string (
1612 GNUNET_TIME_absolute_ntoh (thp.monotonic_time)));
1613 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1614 &thp,
1615 &rekey.sender_sig);
1616 calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1617 /* Encrypt rekey message with 'old' cipher */
1618 GNUNET_assert (0 ==
1619 gcry_cipher_encrypt (queue->out_cipher,
1620 &queue->cwrite_buf[queue->cwrite_off],
1621 sizeof(rekey),
1622 &rekey,
1623 sizeof(rekey)));
1624 queue->cwrite_off += sizeof(rekey);
1625 /* Setup new cipher for successive messages */
1626 gcry_cipher_close (queue->out_cipher);
1627 setup_out_cipher (queue, &k);
1628}
1629
1630
1631static int
1632pending_reversals_delete_it (void *cls,
1633 const struct GNUNET_HashCode *key,
1634 void *value)
1635{
1636 (void) cls;
1637 struct PendingReversal *pending_reversal = value;
1638
1639 if (NULL != pending_reversal->timeout_task)
1640 {
1641 GNUNET_SCHEDULER_cancel (pending_reversal->timeout_task);
1642 pending_reversal->timeout_task = NULL;
1643 }
1644 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (
1645 pending_reversals,
1646 key,
1647 pending_reversal));
1648 GNUNET_free (pending_reversal->in);
1649 GNUNET_free (pending_reversal);
1650 return GNUNET_OK;
1651}
1652
1653
1654static void
1655check_and_remove_pending_reversal (struct sockaddr *in, sa_family_t sa_family,
1656 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,
1674 &pending_reversal->target,
1675 sizeof(struct
1676 GNUNET_PeerIdentity))))
1677 {
1678 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1679 "Removing invalid pending reversal for `%s'at `%s'\n",
1680 GNUNET_i2s (&pending_reversal->target),
1681 GNUNET_a2s (in, sizeof (struct sockaddr)));
1682 pending_reversals_delete_it (NULL, &key, pending_reversal);
1683 }
1684 GNUNET_free (natted_address);
1685 }
1686}
1687
1688
1689/**
1690 * Closes socket and frees memory associated with @a pq.
1691 *
1692 * @param pq proto queue to free
1693 */
1694static void
1695free_proto_queue (struct ProtoQueue *pq)
1696{
1697 if (NULL != pq->listen_sock)
1698 {
1699 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pq->listen_sock));
1700 pq->listen_sock = NULL;
1701 }
1702 if (NULL != pq->read_task)
1703 {
1704 GNUNET_SCHEDULER_cancel (pq->read_task);
1705 pq->read_task = NULL;
1706 }
1707 if (NULL != pq->write_task)
1708 {
1709 GNUNET_SCHEDULER_cancel (pq->write_task);
1710 pq->write_task = NULL;
1711 }
1712 check_and_remove_pending_reversal (pq->address, pq->address->sa_family, NULL);
1713 GNUNET_NETWORK_socket_close (pq->sock);
1714 GNUNET_free (pq->address);
1715 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
1716 GNUNET_free (pq);
1717}
1718
1719
1720/**
1721 * We have been notified that our socket is ready to write.
1722 * Then reschedule this function to be called again once more is available.
1723 *
1724 * @param cls a `struct ProtoQueue`
1725 */
1726static void
1727proto_queue_write (void *cls)
1728{
1729 struct ProtoQueue *pq = cls;
1730 ssize_t sent;
1731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In proto queue write\n");
1732 pq->write_task = NULL;
1733 if (0 != pq->write_off)
1734 {
1735 sent = GNUNET_NETWORK_socket_send (pq->sock,
1736 pq->write_buf,
1737 pq->write_off);
1738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1739 "Sent %lu bytes to TCP queue\n", sent);
1740 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1741 {
1742 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
1743 free_proto_queue (pq);
1744 return;
1745 }
1746 if (sent > 0)
1747 {
1748 size_t usent = (size_t) sent;
1749 pq->write_off -= usent;
1750 memmove (pq->write_buf,
1751 &pq->write_buf[usent],
1752 pq->write_off);
1753 }
1754 }
1755 /* do we care to write more? */
1756 if ((0 < pq->write_off))
1757 pq->write_task =
1758 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1759 pq->sock,
1760 &proto_queue_write,
1761 pq);
1762}
1763
1764
1765/**
1766 * We have been notified that our socket is ready to write.
1767 * Then reschedule this function to be called again once more is available.
1768 *
1769 * @param cls a `struct Queue`
1770 */
1771static void
1772queue_write (void *cls)
1773{
1774 struct Queue *queue = cls;
1775 ssize_t sent;
1776 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1777 queue->write_task = NULL;
1778 if (0 != queue->cwrite_off)
1779 {
1780 sent = GNUNET_NETWORK_socket_send (queue->sock,
1781 queue->cwrite_buf,
1782 queue->cwrite_off);
1783 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1784 "Sent %lu bytes to TCP queue\n", sent);
1785 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1786 {
1787 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
1788 queue_destroy (queue);
1789 return;
1790 }
1791 if (sent > 0)
1792 {
1793 size_t usent = (size_t) sent;
1794 queue->cwrite_off -= usent;
1795 memmove (queue->cwrite_buf,
1796 &queue->cwrite_buf[usent],
1797 queue->cwrite_off);
1798 reschedule_queue_timeout (queue);
1799 }
1800 }
1801 /* can we encrypt more? (always encrypt full messages, needed
1802 such that #mq_cancel() can work!) */
1803 unsigned int we_do_not_need_to_rekey = (0 < queue->rekey_left_bytes
1804 - (queue->cwrite_off
1805 + queue->pwrite_off
1806 + sizeof (struct TCPRekey)));
1807 if (we_do_not_need_to_rekey &&
1808 (queue->pwrite_off > 0) &&
1809 (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1810 {
1811 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1812 "Encrypting %lu bytes\n", queue->pwrite_off);
1813 GNUNET_assert (0 ==
1814 gcry_cipher_encrypt (queue->out_cipher,
1815 &queue->cwrite_buf[queue->cwrite_off],
1816 queue->pwrite_off,
1817 queue->pwrite_buf,
1818 queue->pwrite_off));
1819 if (queue->rekey_left_bytes > queue->pwrite_off)
1820 queue->rekey_left_bytes -= queue->pwrite_off;
1821 else
1822 queue->rekey_left_bytes = 0;
1823 queue->cwrite_off += queue->pwrite_off;
1824 queue->pwrite_off = 0;
1825 }
1826 // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1827 if (((0 == queue->rekey_left_bytes) ||
1828 (0 == GNUNET_TIME_absolute_get_remaining (
1829 queue->rekey_time).rel_value_us)) &&
1830 (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey) &&
1831 (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE)))
1832 {
1833 inject_rekey (queue);
1834 }
1835 if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1836 (GNUNET_YES == queue->mq_awaits_continue))
1837 {
1838 queue->mq_awaits_continue = GNUNET_NO;
1839 GNUNET_MQ_impl_send_continue (queue->mq);
1840 }
1841 /* did we just finish writing 'finish'? */
1842 if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1843 {
1844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1845 "Finishing queue\n");
1846 queue_destroy (queue);
1847 return;
1848 }
1849 /* do we care to write more? */
1850 if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1851 queue->write_task =
1852 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1853 queue->sock,
1854 &queue_write,
1855 queue);
1856}
1857
1858
1859/**
1860 * Test if we have received a full message in plaintext.
1861 * If so, handle it.
1862 *
1863 * @param queue queue to process inbound plaintext for
1864 * @return number of bytes of plaintext handled, 0 for none
1865 */
1866static size_t
1867try_handle_plaintext (struct Queue *queue)
1868{
1869 const struct GNUNET_MessageHeader *hdr;
1870 const struct TCPConfirmationAck *tca;
1871 const struct TCPBox *box;
1872 const struct TCPRekey *rekey;
1873 const struct TCPFinish *fin;
1874 struct TCPRekey rekeyz;
1875 struct TCPFinish finz;
1876 struct GNUNET_ShortHashCode tmac;
1877 uint16_t type;
1878 size_t size = 0;
1879 struct TcpHandshakeAckSignature thas;
1880 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1881
1882 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1883 "try handle plaintext!\n");
1884
1885 hdr = (const struct GNUNET_MessageHeader *) queue->pread_buf;
1886 if ((sizeof(*hdr) > queue->pread_off))
1887 {
1888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1889 "Handling plaintext, not even a header!\n");
1890 return 0; /* not even a header */
1891 }
1892
1893 if ((GNUNET_YES != queue->initial_core_kx_done) && (queue->unverified_size >
1894 INITIAL_CORE_KX_SIZE))
1895 {
1896 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1897 "Already received data of size %lu bigger than KX size %lu!\n",
1898 queue->unverified_size,
1899 INITIAL_CORE_KX_SIZE);
1900 GNUNET_break_op (0);
1901 queue_finish (queue);
1902 return 0;
1903 }
1904
1905 type = ntohs (hdr->type);
1906 switch (type)
1907 {
1908 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK:
1909 tca = (const struct TCPConfirmationAck *) queue->pread_buf;
1910 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1911 "start processing ack\n");
1912 if (sizeof(*tca) > queue->pread_off)
1913 {
1914 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1915 "Handling plaintext size of tca greater than pread offset.\n");
1916 return 0;
1917 }
1918 if (ntohs (hdr->size) != sizeof(*tca))
1919 {
1920 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1921 "Handling plaintext size does not match message type.\n");
1922 GNUNET_break_op (0);
1923 queue_finish (queue);
1924 return 0;
1925 }
1926
1927 thas.purpose.purpose = htonl (
1928 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK);
1929 thas.purpose.size = htonl (sizeof(thas));
1930 thas.sender = tca->sender;
1931 thas.receiver = my_identity;
1932 thas.monotonic_time = tca->monotonic_time;
1933 thas.challenge = tca->challenge;
1934
1935 if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_verify (
1936 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK,
1937 &thas,
1938 &tca->sender_sig,
1939 &tca->sender.public_key))
1940 {
1941 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1942 "Verification of signature failed!\n");
1943 GNUNET_break (0);
1944 queue_finish (queue);
1945 return 0;
1946 }
1947 if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
1948 {
1949 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1950 "Challenge in TCPConfirmationAck not correct!\n");
1951 GNUNET_break (0);
1952 queue_finish (queue);
1953 return 0;
1954 }
1955
1956 queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1957 "transport_tcp_communicator",
1958 &queue->target,
1959 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK,
1960 &
1961 handshake_ack_monotime_cb,
1962 queue);
1963
1964 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1965 "Handling plaintext, ack processed!\n");
1966
1967 if (GNUNET_TRANSPORT_CS_INBOUND == queue->cs)
1968 {
1969 send_challenge (queue->challenge_received, queue);
1970 queue->write_task =
1971 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1972 queue->sock,
1973 &queue_write,
1974 queue);
1975 }
1976 else if (GNUNET_TRANSPORT_CS_OUTBOUND == queue->cs)
1977 {
1978 check_and_remove_pending_reversal (queue->address,
1979 queue->address->sa_family, NULL);
1980 }
1981
1982 /**
1983 * Once we received this ack, we consider this a verified connection.
1984 * FIXME: I am not sure this logic is sane here.
1985 */
1986 queue->initial_core_kx_done = GNUNET_YES;
1987
1988 char *foreign_addr;
1989
1990 switch (queue->address->sa_family)
1991 {
1992 case AF_INET:
1993 GNUNET_asprintf (&foreign_addr,
1994 "%s-%s",
1995 COMMUNICATOR_ADDRESS_PREFIX,
1996 GNUNET_a2s (queue->address, queue->address_len));
1997 break;
1998
1999 case AF_INET6:
2000 GNUNET_asprintf (&foreign_addr,
2001 "%s-%s",
2002 COMMUNICATOR_ADDRESS_PREFIX,
2003 GNUNET_a2s (queue->address, queue->address_len));
2004 break;
2005
2006 default:
2007 GNUNET_assert (0);
2008 }
2009
2010 queue->qh = GNUNET_TRANSPORT_communicator_mq_add (ch,
2011 &queue->target,
2012 foreign_addr,
2013 UINT16_MAX, /* no MTU */
2014 GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED,
2015 0, /* Priority */
2016 queue->nt,
2017 queue->cs,
2018 queue->mq);
2019
2020 GNUNET_free (foreign_addr);
2021
2022 size = ntohs (hdr->size);
2023 break;
2024 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
2025 /* Special case: header size excludes box itself! */
2026 box = (const struct TCPBox *) queue->pread_buf;
2027 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
2028 return 0;
2029 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
2030 if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
2031 {
2032 GNUNET_break_op (0);
2033 queue_finish (queue);
2034 return 0;
2035 }
2036 pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
2037 size = ntohs (hdr->size) + sizeof(*box);
2038 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2039 "Handling plaintext, box processed!\n");
2040 break;
2041
2042 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
2043 rekey = (const struct TCPRekey *) queue->pread_buf;
2044 if (sizeof(*rekey) > queue->pread_off)
2045 return 0;
2046 if (ntohs (hdr->size) != sizeof(*rekey))
2047 {
2048 GNUNET_break_op (0);
2049 queue_finish (queue);
2050 return 0;
2051 }
2052 rekeyz = *rekey;
2053 memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
2054 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
2055 if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
2056 {
2057 GNUNET_break_op (0);
2058 queue_finish (queue);
2059 return 0;
2060 }
2061 do_rekey (queue, rekey);
2062 size = ntohs (hdr->size);
2063 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2064 "Handling plaintext, rekey processed!\n");
2065 break;
2066
2067 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
2068 fin = (const struct TCPFinish *) queue->pread_buf;
2069 if (sizeof(*fin) > queue->pread_off)
2070 return 0;
2071 if (ntohs (hdr->size) != sizeof(*fin))
2072 {
2073 GNUNET_break_op (0);
2074 queue_finish (queue);
2075 return 0;
2076 }
2077 finz = *fin;
2078 memset (&finz.hmac, 0, sizeof(finz.hmac));
2079 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
2080 if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
2081 {
2082 GNUNET_break_op (0);
2083 queue_finish (queue);
2084 return 0;
2085 }
2086 /* handle FINISH by destroying queue */
2087 queue_destroy (queue);
2088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2089 "Handling plaintext, finish processed!\n");
2090 break;
2091
2092 default:
2093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2094 "Handling plaintext, nothing processed!\n");
2095 GNUNET_break_op (0);
2096 queue_finish (queue);
2097 return 0;
2098 }
2099 GNUNET_assert (0 != size);
2100 if (-1 != queue->unverified_size)
2101 queue->unverified_size += size;
2102 return size;
2103}
2104
2105
2106/**
2107 * Queue read task. If we hit the timeout, disconnect it
2108 *
2109 * @param cls the `struct Queue *` to disconnect
2110 */
2111static void
2112queue_read (void *cls)
2113{
2114 struct Queue *queue = cls;
2115 struct GNUNET_TIME_Relative left;
2116 ssize_t rcvd;
2117
2118 queue->read_task = NULL;
2119 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2120 &queue->cread_buf[queue->cread_off],
2121 BUF_SIZE - queue->cread_off);
2122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2123 "Received %zd bytes from TCP queue\n", rcvd);
2124 if (-1 == rcvd)
2125 {
2126 if ((EAGAIN != errno) && (EINTR != errno))
2127 {
2128 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2129 queue_finish (queue);
2130 return;
2131 }
2132 /* try again */
2133 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2134 queue->read_task =
2135 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
2136 return;
2137 }
2138 if (0 != rcvd)
2139 reschedule_queue_timeout (queue);
2140 queue->cread_off += rcvd;
2141 while ((queue->pread_off < sizeof(queue->pread_buf)) &&
2142 (queue->cread_off > 0))
2143 {
2144 size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
2145 queue->cread_off);
2146 size_t done;
2147 size_t total;
2148 size_t old_pread_off = queue->pread_off;
2149
2150 GNUNET_assert (0 ==
2151 gcry_cipher_decrypt (queue->in_cipher,
2152 &queue->pread_buf[queue->pread_off],
2153 max,
2154 queue->cread_buf,
2155 max));
2156 queue->pread_off += max;
2157 total = 0;
2158 while (0 != (done = try_handle_plaintext (queue)))
2159 {
2160 /* 'done' bytes of plaintext were used, shift buffer */
2161 GNUNET_assert (done <= queue->pread_off);
2162 /* NOTE: this memmove() could possibly sometimes be
2163 avoided if we pass 'total' into try_handle_plaintext()
2164 and use it at an offset into the buffer there! */
2165 memmove (queue->pread_buf,
2166 &queue->pread_buf[done],
2167 queue->pread_off - done);
2168 queue->pread_off -= done;
2169 total += done;
2170 /* The last plaintext was a rekey, abort for now */
2171 if (GNUNET_YES == queue->rekeyed)
2172 break;
2173 }
2174 /* when we encounter a rekey message, the decryption above uses the
2175 wrong key for everything after the rekey; in that case, we have
2176 to re-do the decryption at 'total' instead of at 'max'.
2177 However, we have to take into account that the plaintext buffer may have
2178 already contained data and not jumped too far ahead in the ciphertext.
2179 If there is no rekey and the last message is incomplete (max > total),
2180 it is safe to keep the decryption so we shift by 'max' */
2181 if (GNUNET_YES == queue->rekeyed)
2182 {
2183 max = total - old_pread_off;
2184 queue->rekeyed = GNUNET_NO;
2185 queue->pread_off = 0;
2186 }
2187 memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
2188 queue->cread_off -= max;
2189 }
2190 if (BUF_SIZE == queue->cread_off)
2191 return; /* buffer full, suspend reading */
2192 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2193 if (0 != left.rel_value_us)
2194 {
2195 if (max_queue_length > queue->backpressure)
2196 {
2197 /* continue reading */
2198 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2199 queue->read_task =
2200 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
2201 }
2202 return;
2203 }
2204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2205 "Queue %p was idle for %s, disconnecting\n",
2206 queue,
2207 GNUNET_STRINGS_relative_time_to_string (
2208 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2209 GNUNET_YES));
2210 queue_finish (queue);
2211}
2212
2213
2214/**
2215 * Convert a `struct sockaddr_in6 to a `struct sockaddr *`
2216 *
2217 * @param[out] sock_len set to the length of the address.
2218 * @param v6 The sockaddr_in6 to be converted.
2219 * @return The struct sockaddr *.
2220 */
2221static struct sockaddr *
2222tcp_address_to_sockaddr_numeric_v6 (socklen_t *sock_len,
2223 struct sockaddr_in6 v6,
2224 unsigned int port)
2225{
2226 struct sockaddr *in;
2227
2228 v6.sin6_family = AF_INET6;
2229 v6.sin6_port = htons ((uint16_t) port);
2230#if HAVE_SOCKADDR_IN_SIN_LEN
2231 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2232#endif
2233 v6.sin6_flowinfo = 0;
2234 v6.sin6_scope_id = 0;
2235 in = GNUNET_memdup (&v6, sizeof(v6));
2236 *sock_len = sizeof(struct sockaddr_in6);
2237
2238 return in;
2239}
2240
2241
2242/**
2243 * Convert a `struct sockaddr_in4 to a `struct sockaddr *`
2244 *
2245 * @param[out] sock_len set to the length of the address.
2246 * @param v4 The sockaddr_in4 to be converted.
2247 * @return The struct sockaddr *.
2248 */
2249static struct sockaddr *
2250tcp_address_to_sockaddr_numeric_v4 (socklen_t *sock_len,
2251 struct sockaddr_in v4,
2252 unsigned int port)
2253{
2254 struct sockaddr *in;
2255
2256 v4.sin_family = AF_INET;
2257 v4.sin_port = htons ((uint16_t) port);
2258#if HAVE_SOCKADDR_IN_SIN_LEN
2259 v4.sin_len = sizeof(struct sockaddr_in);
2260#endif
2261 in = GNUNET_memdup (&v4, sizeof(v4));
2262 *sock_len = sizeof(struct sockaddr_in);
2263 return in;
2264}
2265
2266
2267/**
2268 * Convert TCP bind specification to a `struct PortOnlyIpv4Ipv6 *`
2269 *
2270 * @param bindto bind specification to convert.
2271 * @return The converted bindto specification.
2272 */
2273static struct PortOnlyIpv4Ipv6 *
2274tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
2275{
2276 struct PortOnlyIpv4Ipv6 *po;
2277 struct sockaddr_in *i4;
2278 struct sockaddr_in6 *i6;
2279 socklen_t sock_len_ipv4;
2280 socklen_t sock_len_ipv6;
2281
2282 /* interpreting value as just a PORT number */
2283 if (*port > UINT16_MAX)
2284 {
2285 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2286 "BINDTO specification `%s' invalid: value too large for port\n",
2287 bindto);
2288 return NULL;
2289 }
2290
2291 po = GNUNET_new (struct PortOnlyIpv4Ipv6);
2292
2293 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2294 (GNUNET_YES ==
2295 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2296 COMMUNICATOR_CONFIG_SECTION,
2297 "DISABLE_V6")))
2298 {
2299 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2300 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2301 *port);
2302 po->addr_len_ipv4 = sock_len_ipv4;
2303 }
2304 else
2305 {
2306
2307 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2308 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2309 *port);
2310 po->addr_len_ipv4 = sock_len_ipv4;
2311
2312 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2313 po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
2314 *port);
2315
2316 po->addr_len_ipv6 = sock_len_ipv6;
2317
2318 GNUNET_free (i6);
2319 }
2320
2321 GNUNET_free (i4);
2322
2323 return po;
2324}
2325
2326
2327/**
2328 * This Method extracts the address part of the BINDTO string.
2329 *
2330 * @param bindto String we extract the address part from.
2331 * @return The extracted address string.
2332 */
2333static char *
2334extract_address (const char *bindto)
2335{
2336 char *addr;
2337 char *start;
2338 char *token;
2339 char *cp;
2340 char *rest = NULL;
2341 char *res;
2342
2343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2344 "extract address with bindto %s\n",
2345 bindto);
2346
2347 if (NULL == bindto)
2348 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2349 "bindto is NULL\n");
2350
2351 cp = GNUNET_strdup (bindto);
2352
2353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2354 "extract address 2\n");
2355
2356 start = cp;
2357 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2358 {
2359 start++; /* skip over '['*/
2360 cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
2361 addr = GNUNET_strdup (start);
2362 }
2363 else
2364 {
2365 token = strtok_r (cp, "]", &rest);
2366 if (strlen (bindto) == strlen (token))
2367 {
2368 token = strtok_r (cp, ":", &rest);
2369 addr = GNUNET_strdup (token);
2370 }
2371 else
2372 {
2373 token++;
2374 res = GNUNET_strdup (token);
2375 addr = GNUNET_strdup (res);
2376 }
2377 }
2378
2379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2380 "tcp address: %s\n",
2381 addr);
2382 GNUNET_free (cp);
2383 return addr;
2384}
2385
2386
2387/**
2388 * This Method extracts the port part of the BINDTO string.
2389 *
2390 * @param addr_and_port String we extract the port from.
2391 * @return The extracted port as unsigned int.
2392 */
2393static unsigned int
2394extract_port (const char *addr_and_port)
2395{
2396 unsigned int port;
2397 char dummy[2];
2398 char *token;
2399 char *addr;
2400 char *colon;
2401 char *cp;
2402 char *rest = NULL;
2403
2404 if (NULL != addr_and_port)
2405 {
2406 cp = GNUNET_strdup (addr_and_port);
2407 token = strtok_r (cp, "]", &rest);
2408 if (strlen (addr_and_port) == strlen (token))
2409 {
2410 colon = strrchr (cp, ':');
2411 if (NULL == colon)
2412 {
2413 GNUNET_free (cp);
2414 return 0;
2415 }
2416 addr = colon;
2417 addr++;
2418 }
2419 else
2420 {
2421 token = strtok_r (NULL, "]", &rest);
2422 if (NULL == token)
2423 {
2424 GNUNET_free (cp);
2425 return 0;
2426 }
2427 else
2428 {
2429 addr = token;
2430 addr++;
2431 }
2432 }
2433
2434
2435 if (1 == sscanf (addr, "%u%1s", &port, dummy))
2436 {
2437 /* interpreting value as just a PORT number */
2438 if (port > UINT16_MAX)
2439 {
2440 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2441 "Port `%u' invalid: value too large for port\n",
2442 port);
2443 GNUNET_free (cp);
2444 return 0;
2445 }
2446 }
2447 else
2448 {
2449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2450 "BINDTO specification invalid: last ':' not followed by number\n");
2451 GNUNET_free (cp);
2452 return 0;
2453 }
2454 GNUNET_free (cp);
2455 }
2456 else
2457 {
2458 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2459 "return 0\n");
2460 /* interpret missing port as 0, aka pick any free one */
2461 port = 0;
2462 }
2463
2464 return port;
2465}
2466
2467
2468/**
2469 * Convert TCP bind specification to a `struct sockaddr *`
2470 *
2471 * @param bindto bind specification to convert
2472 * @param[out] sock_len set to the length of the address
2473 * @return converted bindto specification
2474 */
2475static struct sockaddr *
2476tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2477{
2478 struct sockaddr *in;
2479 unsigned int port;
2480 struct sockaddr_in v4;
2481 struct sockaddr_in6 v6;
2482 char *start;
2483
2484 memset (&v4, 0, sizeof(v4));
2485 start = extract_address (bindto);
2486 GNUNET_assert (NULL != start);
2487 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2488 "start %s\n",
2489 start);
2490
2491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2492 "!bindto %s\n",
2493 bindto);
2494
2495
2496 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2497 {
2498 // colon = strrchr (cp, ':');
2499 port = extract_port (bindto);
2500
2501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2502 "port %u\n",
2503 port);
2504
2505 in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
2506 }
2507 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2508 {
2509 // colon = strrchr (cp, ':');
2510 port = extract_port (bindto);
2511 in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
2512 }
2513 else
2514 {
2515 GNUNET_assert (0);
2516 }
2517
2518 GNUNET_free (start);
2519 return in;
2520}
2521
2522
2523/**
2524 * Signature of functions implementing the sending functionality of a
2525 * message queue.
2526 *
2527 * @param mq the message queue
2528 * @param msg the message to send
2529 * @param impl_state our `struct Queue`
2530 */
2531static void
2532mq_send (struct GNUNET_MQ_Handle *mq,
2533 const struct GNUNET_MessageHeader *msg,
2534 void *impl_state)
2535{
2536 struct Queue *queue = impl_state;
2537 uint16_t msize = ntohs (msg->size);
2538 struct TCPBox box;
2539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2540 "In MQ send. Queue finishing: %s; write task running: %s\n",
2541 (GNUNET_YES == queue->finishing) ? "yes" : "no",
2542 (NULL == queue->write_task) ? "yes" : "no");
2543 GNUNET_assert (mq == queue->mq);
2544 queue->mq_awaits_continue = GNUNET_YES;
2545 if (GNUNET_YES == queue->finishing)
2546 return; /* this queue is dying, drop msg */
2547 GNUNET_assert (0 == queue->pwrite_off);
2548 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
2549 box.header.size = htons (msize);
2550 calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
2551 memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
2552 queue->pwrite_off += sizeof(box);
2553 memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
2554 queue->pwrite_off += msize;
2555 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2556 "%lu bytes of plaintext to send\n", queue->pwrite_off);
2557 GNUNET_assert (NULL != queue->sock);
2558 if (NULL == queue->write_task)
2559 queue->write_task =
2560 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2561 queue->sock,
2562 &queue_write,
2563 queue);
2564}
2565
2566
2567/**
2568 * Signature of functions implementing the destruction of a message
2569 * queue. Implementations must not free @a mq, but should take care
2570 * of @a impl_state.
2571 *
2572 * @param mq the message queue to destroy
2573 * @param impl_state our `struct Queue`
2574 */
2575static void
2576mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
2577{
2578 struct Queue *queue = impl_state;
2579
2580 if (mq == queue->mq)
2581 {
2582 queue->mq = NULL;
2583 queue_finish (queue);
2584 }
2585}
2586
2587
2588/**
2589 * Implementation function that cancels the currently sent message.
2590 *
2591 * @param mq message queue
2592 * @param impl_state our `struct Queue`
2593 */
2594static void
2595mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2596{
2597 struct Queue *queue = impl_state;
2598
2599 GNUNET_assert (0 != queue->pwrite_off);
2600 queue->pwrite_off = 0;
2601}
2602
2603
2604/**
2605 * Generic error handler, called with the appropriate
2606 * error code and the same closure specified at the creation of
2607 * the message queue.
2608 * Not every message queue implementation supports an error handler.
2609 *
2610 * @param cls our `struct Queue`
2611 * @param error error code
2612 */
2613static void
2614mq_error (void *cls, enum GNUNET_MQ_Error error)
2615{
2616 struct Queue *queue = cls;
2617
2618 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2619 "MQ error in queue to %s: %d\n",
2620 GNUNET_i2s (&queue->target),
2621 (int) error);
2622 queue_finish (queue);
2623}
2624
2625
2626/**
2627 * Add the given @a queue to our internal data structure. Setup the
2628 * MQ processing and inform transport that the queue is ready. Must
2629 * be called after the KX for outgoing messages has been bootstrapped.
2630 *
2631 * @param queue queue to boot
2632 */
2633static void
2634boot_queue (struct Queue *queue)
2635{
2636 queue->nt =
2637 GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
2638 (void) GNUNET_CONTAINER_multipeermap_put (
2639 queue_map,
2640 &queue->target,
2641 queue,
2642 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2643 GNUNET_STATISTICS_set (stats,
2644 "# queues active",
2645 GNUNET_CONTAINER_multipeermap_size (queue_map),
2646 GNUNET_NO);
2647 queue->timeout =
2648 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2649 queue->mq = GNUNET_MQ_queue_for_callbacks (&mq_send,
2650 &mq_destroy,
2651 &mq_cancel,
2652 queue,
2653 NULL,
2654 &mq_error,
2655 queue);
2656}
2657
2658
2659/**
2660 * Generate and transmit our ephemeral key and the signature for
2661 * the initial KX with the other peer. Must be called first, before
2662 * any other bytes are ever written to the output buffer. Note that
2663 * our cipher must already be initialized when calling this function.
2664 * Helper function for #start_initial_kx_out().
2665 *
2666 * @param queue queue to do KX for
2667 * @param epub our public key for the KX
2668 */
2669static void
2670transmit_kx (struct Queue *queue,
2671 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
2672{
2673 struct TcpHandshakeSignature ths;
2674 struct TCPConfirmation tc;
2675
2676 memcpy (queue->cwrite_buf, epub, sizeof(*epub));
2677 queue->cwrite_off = sizeof(*epub);
2678 /* compute 'tc' and append in encrypted format to cwrite_buf */
2679 tc.sender = my_identity;
2680 tc.monotonic_time =
2681 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
2682 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
2683 &tc.challenge,
2684 sizeof(tc.challenge));
2685 ths.purpose.purpose = htonl (
2686 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2687 ths.purpose.size = htonl (sizeof(ths));
2688 ths.sender = my_identity;
2689 ths.receiver = queue->target;
2690 ths.ephemeral = *epub;
2691 ths.monotonic_time = tc.monotonic_time;
2692 ths.challenge = tc.challenge;
2693 GNUNET_CRYPTO_eddsa_sign (my_private_key,
2694 &ths,
2695 &tc.sender_sig);
2696 GNUNET_assert (0 ==
2697 gcry_cipher_encrypt (queue->out_cipher,
2698 &queue->cwrite_buf[queue->cwrite_off],
2699 sizeof(tc),
2700 &tc,
2701 sizeof(tc)));
2702 queue->challenge = tc.challenge;
2703 queue->cwrite_off += sizeof(tc);
2704
2705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2706 "handshake written\n");
2707}
2708
2709
2710/**
2711 * Initialize our key material for outgoing transmissions and
2712 * inform the other peer about it. Must be called first before
2713 * any data is sent.
2714 *
2715 * @param queue the queue to setup
2716 */
2717static void
2718start_initial_kx_out (struct Queue *queue)
2719{
2720 struct GNUNET_CRYPTO_EcdhePublicKey epub;
2721 struct GNUNET_HashCode k;
2722
2723 GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &epub, &k);
2724 setup_out_cipher (queue, &k);
2725 transmit_kx (queue, &epub);
2726}
2727
2728
2729/**
2730 * Callback called when peerstore store operation for handshake monotime is finished.
2731 * @param cls Queue context the store operation was executed.
2732 * @param success Store operation was successful (GNUNET_OK) or not.
2733 */
2734static void
2735handshake_monotime_store_cb (void *cls, int success)
2736{
2737 struct Queue *queue = cls;
2738 if (GNUNET_OK != success)
2739 {
2740 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2741 "Failed to store handshake monotonic time in PEERSTORE!\n");
2742 }
2743 queue->handshake_monotime_sc = NULL;
2744}
2745
2746
2747/**
2748 * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE
2749 * where found.
2750 * @param cls Queue context the store operation was executed.
2751 * @param record The record found or NULL if there is no record left.
2752 * @param emsg Message from peerstore.
2753 */
2754static void
2755handshake_monotime_cb (void *cls,
2756 const struct GNUNET_PEERSTORE_Record *record,
2757 const char *emsg)
2758{
2759 struct Queue *queue = cls;
2760 struct GNUNET_TIME_AbsoluteNBO *mtbe;
2761 struct GNUNET_TIME_Absolute mt;
2762 const struct GNUNET_PeerIdentity *pid;
2763 struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2764
2765 (void) emsg;
2766
2767 handshake_monotonic_time = &queue->handshake_monotonic_time;
2768 pid = &queue->target;
2769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2770 "tcp handshake with us %s\n",
2771 GNUNET_i2s (&my_identity));
2772 if (NULL == record)
2773 {
2774 queue->handshake_monotime_get = NULL;
2775 return;
2776 }
2777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2778 "tcp handshake from peer %s\n",
2779 GNUNET_i2s (pid));
2780 if (sizeof(*mtbe) != record->value_size)
2781 {
2782 GNUNET_break (0);
2783 return;
2784 }
2785 mtbe = record->value;
2786 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2787 if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
2788 queue->handshake_monotonic_time).abs_value_us)
2789 {
2790 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2791 "Queue from %s dropped, handshake monotime in the past\n",
2792 GNUNET_i2s (&queue->target));
2793 GNUNET_break (0);
2794 queue_finish (queue);
2795 return;
2796 }
2797 queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2798 "transport_tcp_communicator",
2799 pid,
2800 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
2801 handshake_monotonic_time,
2802 sizeof(*
2803 handshake_monotonic_time),
2804 GNUNET_TIME_UNIT_FOREVER_ABS,
2805 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
2806 &
2807 handshake_monotime_store_cb,
2808 queue);
2809}
2810
2811
2812/**
2813 * We have received the first bytes from the other side on a @a queue.
2814 * Decrypt the @a tc contained in @a ibuf and check the signature.
2815 * Note that #setup_in_cipher() must have already been called.
2816 *
2817 * @param queue queue to decrypt initial bytes from other peer for
2818 * @param[out] tc where to store the result
2819 * @param ibuf incoming data, of size
2820 * `INITIAL_KX_SIZE`
2821 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
2822 */
2823static int
2824decrypt_and_check_tc (struct Queue *queue,
2825 struct TCPConfirmation *tc,
2826 char *ibuf)
2827{
2828 struct TcpHandshakeSignature ths;
2829 enum GNUNET_GenericReturnValue ret;
2830
2831 GNUNET_assert (
2832 0 ==
2833 gcry_cipher_decrypt (queue->in_cipher,
2834 tc,
2835 sizeof(*tc),
2836 &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2837 sizeof(*tc)));
2838 ths.purpose.purpose = htonl (
2839 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2840 ths.purpose.size = htonl (sizeof(ths));
2841 ths.sender = tc->sender;
2842 ths.receiver = my_identity;
2843 memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2844 ths.monotonic_time = tc->monotonic_time;
2845 ths.challenge = tc->challenge;
2846 ret = GNUNET_CRYPTO_eddsa_verify (
2847 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE,
2848 &ths,
2849 &tc->sender_sig,
2850 &tc->sender.public_key);
2851 if (GNUNET_YES == ret)
2852 queue->handshake_monotime_get =
2853 GNUNET_PEERSTORE_iterate (peerstore,
2854 "transport_tcp_communicator",
2855 &queue->target,
2856 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
2857 &handshake_monotime_cb,
2858 queue);
2859 return ret;
2860}
2861
2862
2863/**
2864 * Read from the socket of the queue until we have enough data
2865 * to initialize the decryption logic and can switch to regular
2866 * reading.
2867 *
2868 * @param cls a `struct Queue`
2869 */
2870static void
2871queue_read_kx (void *cls)
2872{
2873 struct Queue *queue = cls;
2874 ssize_t rcvd;
2875 struct GNUNET_TIME_Relative left;
2876 struct TCPConfirmation tc;
2877
2878 queue->read_task = NULL;
2879 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2880 if (0 == left.rel_value_us)
2881 {
2882 queue_destroy (queue);
2883 return;
2884 }
2885 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2886 &queue->cread_buf[queue->cread_off],
2887 BUF_SIZE - queue->cread_off);
2888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2889 "Received %lu bytes for KX\n",
2890 rcvd);
2891 if (-1 == rcvd)
2892 {
2893 if ((EAGAIN != errno) && (EINTR != errno))
2894 {
2895 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2896 queue_destroy (queue);
2897 return;
2898 }
2899 queue->read_task =
2900 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
2901 return;
2902 }
2903 queue->cread_off += rcvd;
2904 if (queue->cread_off < INITIAL_KX_SIZE)
2905 {
2906 /* read more */
2907 queue->read_task =
2908 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
2909 return;
2910 }
2911 /* we got all the data, let's find out who we are talking to! */
2912 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *)
2913 queue->cread_buf,
2914 queue);
2915 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
2916 {
2917 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2918 "Invalid TCP KX received from %s\n",
2919 GNUNET_a2s (queue->address, queue->address_len));
2920 queue_destroy (queue);
2921 return;
2922 }
2923 if (0 !=
2924 memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
2925 {
2926 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2927 "Invalid sender in TCP KX received from %s\n",
2928 GNUNET_a2s (queue->address, queue->address_len));
2929 queue_destroy (queue);
2930 return;
2931 }
2932 send_challenge (tc.challenge, queue);
2933 queue->write_task =
2934 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2935 queue->sock,
2936 &queue_write,
2937 queue);
2938
2939 /* update queue timeout */
2940 reschedule_queue_timeout (queue);
2941 /* prepare to continue with regular read task immediately */
2942 memmove (queue->cread_buf,
2943 &queue->cread_buf[INITIAL_KX_SIZE],
2944 queue->cread_off - (INITIAL_KX_SIZE));
2945 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2946 "cread_off is %lu bytes before adjusting\n",
2947 queue->cread_off);
2948 queue->cread_off -= INITIAL_KX_SIZE;
2949 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2950 "cread_off set to %lu bytes\n",
2951 queue->cread_off);
2952 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue);
2953}
2954
2955
2956/**
2957 * Read from the socket of the proto queue until we have enough data
2958 * to upgrade to full queue.
2959 *
2960 * @param cls a `struct ProtoQueue`
2961 */
2962static void
2963proto_read_kx (void *cls)
2964{
2965 struct ProtoQueue *pq = cls;
2966 ssize_t rcvd;
2967 struct GNUNET_TIME_Relative left;
2968 struct Queue *queue;
2969 struct TCPConfirmation tc;
2970 GNUNET_SCHEDULER_TaskCallback read_task;
2971
2972 pq->read_task = NULL;
2973 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
2974 if (0 == left.rel_value_us)
2975 {
2976 free_proto_queue (pq);
2977 return;
2978 }
2979 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
2980 &pq->ibuf[pq->ibuf_off],
2981 sizeof(pq->ibuf) - pq->ibuf_off);
2982 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2983 "Proto received %lu bytes for KX\n", rcvd);
2984 if (-1 == rcvd)
2985 {
2986 if ((EAGAIN != errno) && (EINTR != errno))
2987 {
2988 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2989 free_proto_queue (pq);
2990 return;
2991 }
2992 /* try again */
2993 pq->read_task =
2994 GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq);
2995 return;
2996 }
2997 pq->ibuf_off += rcvd;
2998 if (sizeof (struct TCPNATProbeMessage) == pq->ibuf_off)
2999 {
3000 struct TCPNATProbeMessage *pm = (struct TCPNATProbeMessage *) pq->ibuf;
3001
3002 check_and_remove_pending_reversal (pq->address, pq->address->sa_family,
3003 &pm->clientIdentity);
3004
3005 queue = GNUNET_new (struct Queue);
3006 queue->target = pm->clientIdentity;
3007 queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND;
3008 read_task = &queue_read_kx;
3009 }
3010 else if (pq->ibuf_off > sizeof(pq->ibuf))
3011 {
3012 /* read more */
3013 pq->read_task =
3014 GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq);
3015 return;
3016 }
3017 else
3018 {
3019 /* we got all the data, let's find out who we are talking to! */
3020 queue = GNUNET_new (struct Queue);
3021 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
3022 queue);
3023 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
3024 {
3025 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3026 "Invalid TCP KX received from %s\n",
3027 GNUNET_a2s (pq->address, pq->address_len));
3028 gcry_cipher_close (queue->in_cipher);
3029 GNUNET_free (queue);
3030 free_proto_queue (pq);
3031 return;
3032 }
3033 queue->target = tc.sender;
3034 queue->cs = GNUNET_TRANSPORT_CS_INBOUND;
3035 read_task = &queue_read;
3036 }
3037 queue->address = pq->address; /* steals reference */
3038 queue->address_len = pq->address_len;
3039 queue->listen_sock = pq->listen_sock;
3040 queue->sock = pq->sock;
3041
3042 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3043 "created queue with target %s\n",
3044 GNUNET_i2s (&queue->target));
3045
3046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3047 "start kx proto\n");
3048
3049 start_initial_kx_out (queue);
3050 boot_queue (queue);
3051 queue->read_task =
3052 GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3053 queue->sock,
3054 read_task,
3055 queue);
3056 queue->write_task =
3057 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3058 queue->sock,
3059 &queue_write,
3060 queue);
3061 // TODO To early! Move it somewhere else.
3062 // send_challenge (tc.challenge, queue);
3063 queue->challenge_received = tc.challenge;
3064
3065 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
3066 GNUNET_free (pq);
3067}
3068
3069
3070static struct ProtoQueue *
3071create_proto_queue (struct GNUNET_NETWORK_Handle *sock,
3072 struct sockaddr *in,
3073 socklen_t addrlen)
3074{
3075 struct ProtoQueue *pq = GNUNET_new (struct ProtoQueue);
3076
3077 if (NULL == sock)
3078 {
3079 // sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, addr, addrlen);
3080 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, 0);
3081 if (NULL == sock)
3082 {
3083 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3084 "socket(%d) failed: %s",
3085 in->sa_family,
3086 strerror (errno));
3087 GNUNET_free (in);
3088 GNUNET_free (pq);
3089 return NULL;
3090 }
3091 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, addrlen)) &&
3092 (errno != EINPROGRESS))
3093 {
3094 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3095 "connect to `%s' failed: %s",
3096 GNUNET_a2s (in, addrlen),
3097 strerror (errno));
3098 GNUNET_NETWORK_socket_close (sock);
3099 GNUNET_free (in);
3100 return NULL;
3101 }
3102 }
3103 pq->address_len = addrlen;
3104 pq->address = in;
3105 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
3106 pq->sock = sock;
3107 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
3108 pq->sock,
3109 &proto_read_kx,
3110 pq);
3111 GNUNET_CONTAINER_DLL_insert (proto_head, proto_tail, pq);
3112
3113 return pq;
3114}
3115
3116
3117/**
3118 * We have been notified that our listen socket has something to
3119 * read. Do the read and reschedule this function to be called again
3120 * once more is available.
3121 *
3122 * @param cls ListenTask with listening socket and task
3123 */
3124static void
3125listen_cb (void *cls)
3126{
3127 struct sockaddr_storage in;
3128 socklen_t addrlen;
3129 struct GNUNET_NETWORK_Handle *sock;
3130 struct ProtoQueue *pq;
3131 struct ListenTask *lt;
3132 struct sockaddr *in_addr;
3133
3134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3135 "listen_cb\n");
3136
3137 lt = cls;
3138
3139 lt->listen_task = NULL;
3140 GNUNET_assert (NULL != lt->listen_sock);
3141 addrlen = sizeof(in);
3142 memset (&in, 0, sizeof(in));
3143 sock = GNUNET_NETWORK_socket_accept (lt->listen_sock,
3144 (struct sockaddr*) &in,
3145 &addrlen);
3146 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
3147 return; /* system limit reached, wait until connection goes down */
3148 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3149 lt->listen_sock,
3150 &listen_cb,
3151 lt);
3152 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
3153 return;
3154 if (NULL == sock)
3155 {
3156 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
3157 return;
3158 }
3159 in_addr = GNUNET_memdup (&in, addrlen);
3160 create_proto_queue (sock, in_addr, addrlen);
3161}
3162
3163
3164static void
3165try_connection_reversal (void *cls,
3166 const struct sockaddr *addr,
3167 socklen_t addrlen)
3168{
3169 (void) cls;
3170 struct TCPNATProbeMessage pm;
3171 struct ProtoQueue *pq;
3172 struct sockaddr *in_addr;
3173
3174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3175 "addr->sa_family %d\n",
3176 addr->sa_family);
3177 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3178 "Try to connect back\n");
3179 in_addr = GNUNET_memdup (addr, addrlen);
3180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3181 "in_addr->sa_family %d\n",
3182 in_addr->sa_family);
3183 pq = create_proto_queue (NULL, in_addr, addrlen);
3184 if (NULL != pq)
3185 {
3186 pm.header.size = htons (sizeof(struct TCPNATProbeMessage));
3187 pm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE);
3188 pm.clientIdentity = my_identity;
3189 memcpy (pq->write_buf, &pm, sizeof(struct TCPNATProbeMessage));
3190 pq->write_off = sizeof(struct TCPNATProbeMessage);
3191 pq->write_task = GNUNET_SCHEDULER_add_write_net (PROTO_QUEUE_TIMEOUT,
3192 pq->sock,
3193 &proto_queue_write,
3194 pq);
3195 }
3196 else
3197 {
3198 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3199 "Couldn't create ProtoQueue for sending TCPNATProbeMessage\n");
3200 }
3201}
3202
3203
3204static void
3205pending_reversal_timeout (void *cls)
3206{
3207 struct sockaddr *in = cls;
3208 struct PendingReversal *pending_reversal;
3209 struct GNUNET_HashCode key;
3210
3211 GNUNET_CRYPTO_hash (in,
3212 sizeof(struct sockaddr),
3213 &key);
3214 pending_reversal = GNUNET_CONTAINER_multihashmap_get (pending_reversals,
3215 &key);
3216
3217 GNUNET_assert (NULL != pending_reversal);
3218
3219 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (pending_reversals,
3220 &key,
3221 pending_reversal))
3222 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3223 "No pending reversal found for address %s\n",
3224 GNUNET_a2s (in, sizeof (struct sockaddr)));
3225 GNUNET_free (pending_reversal->in);
3226 GNUNET_free (pending_reversal);
3227}
3228
3229
3230/**
3231 * Function called by the transport service to initialize a
3232 * message queue given address information about another peer.
3233 * If and when the communication channel is established, the
3234 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
3235 * to notify the service that the channel is now up. It is
3236 * the responsibility of the communicator to manage sane
3237 * retries and timeouts for any @a peer/@a address combination
3238 * provided by the transport service. Timeouts and retries
3239 * do not need to be signalled to the transport service.
3240 *
3241 * @param cls closure
3242 * @param peer identity of the other peer
3243 * @param address where to send the message, human-readable
3244 * communicator-specific format, 0-terminated, UTF-8
3245 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is
3246 * invalid
3247 */
3248static int
3249mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3250{
3251 struct sockaddr *in;
3252 socklen_t in_len = 0;
3253 const char *path;
3254 struct sockaddr_in *v4;
3255 struct sockaddr_in6 *v6;
3256 unsigned int is_natd = GNUNET_NO;
3257 struct GNUNET_HashCode key;
3258
3259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3260 "Connecting to %s at %s\n",
3261 GNUNET_i2s (peer),
3262 address);
3263 if (0 != strncmp (address,
3264 COMMUNICATOR_ADDRESS_PREFIX "-",
3265 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
3266 {
3267 GNUNET_break_op (0);
3268 return GNUNET_SYSERR;
3269 }
3270 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
3271 in = tcp_address_to_sockaddr (path, &in_len);
3272
3273 if (NULL == in)
3274 {
3275 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3276 "Failed to setup TCP socket address\n");
3277 return GNUNET_SYSERR;
3278 }
3279
3280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3281 "in %s\n",
3282 GNUNET_a2s (in, in_len));
3283
3284 switch (in->sa_family)
3285 {
3286 case AF_INET:
3287 v4 = (struct sockaddr_in *) in;
3288 if (0 == v4->sin_port)
3289 {
3290 is_natd = GNUNET_YES;
3291 GNUNET_CRYPTO_hash (in,
3292 sizeof(struct sockaddr),
3293 &key);
3294 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (
3295 pending_reversals,
3296 &key))
3297 {
3298 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3299 "There is already a request reversal for `%s'at `%s'\n",
3300 GNUNET_i2s (peer),
3301 address);
3302 GNUNET_free (in);
3303 return GNUNET_SYSERR;
3304 }
3305 }
3306 break;
3307
3308 case AF_INET6:
3309 v6 = (struct sockaddr_in6 *) in;
3310 if (0 == v6->sin6_port)
3311 {
3312 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3313 "Request reversal for `%s' at `%s' not possible for an IPv6 address\n",
3314 GNUNET_i2s (peer),
3315 address);
3316 GNUNET_free (in);
3317 return GNUNET_SYSERR;
3318 }
3319 break;
3320
3321 default:
3322 GNUNET_assert (0);
3323 }
3324
3325 if (GNUNET_YES == is_natd)
3326 {
3327 struct sockaddr_in local_sa;
3328 struct PendingReversal *pending_reversal;
3329
3330 memset (&local_sa, 0, sizeof(local_sa));
3331 local_sa.sin_family = AF_INET;
3332 local_sa.sin_port = htons (bind_port);
3333 /* We leave sin_address at 0, let the kernel figure it out,
3334 even if our bind() is more specific. (May want to reconsider
3335 later.) */
3336 if (GNUNET_OK != GNUNET_NAT_request_reversal (nat, &local_sa, v4))
3337 {
3338 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3339 "request reversal for `%s' at `%s' failed\n",
3340 GNUNET_i2s (peer),
3341 address);
3342 GNUNET_free (in);
3343 return GNUNET_SYSERR;
3344 }
3345 pending_reversal = GNUNET_new (struct PendingReversal);
3346 pending_reversal->in = in;
3347 GNUNET_assert (GNUNET_OK ==
3348 GNUNET_CONTAINER_multihashmap_put (pending_reversals,
3349 &key,
3350 pending_reversal,
3351 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3352 pending_reversal->target = *peer;
3353 pending_reversal->timeout_task = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT,
3354 &
3355 pending_reversal_timeout,
3356 in);
3357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3358 "Created NAT WAIT connection to `%s' at `%s'\n",
3359 GNUNET_i2s (peer),
3360 GNUNET_a2s (in, sizeof (struct sockaddr)));
3361 }
3362 else
3363 {
3364 struct GNUNET_NETWORK_Handle *sock;
3365 struct Queue *queue;
3366
3367 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM,
3368 IPPROTO_TCP);
3369 if (NULL == sock)
3370 {
3371 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3372 "socket(%d) failed: %s",
3373 in->sa_family,
3374 strerror (errno));
3375 GNUNET_free (in);
3376 return GNUNET_SYSERR;
3377 }
3378 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
3379 (errno != EINPROGRESS))
3380 {
3381 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3382 "connect to `%s' failed: %s",
3383 address,
3384 strerror (errno));
3385 GNUNET_NETWORK_socket_close (sock);
3386 GNUNET_free (in);
3387 return GNUNET_SYSERR;
3388 }
3389
3390 queue = GNUNET_new (struct Queue);
3391 queue->target = *peer;
3392 queue->address = in;
3393 queue->address_len = in_len;
3394 queue->sock = sock;
3395 queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND;
3396 boot_queue (queue);
3397 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3398 "booted queue with target %s\n",
3399 GNUNET_i2s (&queue->target));
3400 // queue->mq_awaits_continue = GNUNET_YES;
3401 queue->read_task =
3402 GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3403 queue->sock,
3404 &queue_read_kx,
3405 queue);
3406
3407
3408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3409 "start kx mq_init\n");
3410
3411 start_initial_kx_out (queue);
3412 queue->write_task =
3413 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3414 queue->sock,
3415 &queue_write,
3416 queue);
3417 }
3418
3419 return GNUNET_OK;
3420}
3421
3422
3423/**
3424 * Iterator over all ListenTasks to clean up.
3425 *
3426 * @param cls NULL
3427 * @param key unused
3428 * @param value the ListenTask to cancel.
3429 * @return #GNUNET_OK to continue to iterate
3430 */
3431static int
3432get_lt_delete_it (void *cls,
3433 const struct GNUNET_HashCode *key,
3434 void *value)
3435{
3436 struct ListenTask *lt = value;
3437
3438 (void) cls;
3439 (void) key;
3440 if (NULL != lt->listen_task)
3441 {
3442 GNUNET_SCHEDULER_cancel (lt->listen_task);
3443 lt->listen_task = NULL;
3444 }
3445 if (NULL != lt->listen_sock)
3446 {
3447 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lt->listen_sock));
3448 lt->listen_sock = NULL;
3449 }
3450 GNUNET_free (lt);
3451 return GNUNET_OK;
3452}
3453
3454
3455/**
3456 * Iterator over all message queues to clean up.
3457 *
3458 * @param cls NULL
3459 * @param target unused
3460 * @param value the queue to destroy
3461 * @return #GNUNET_OK to continue to iterate
3462 */
3463static int
3464get_queue_delete_it (void *cls,
3465 const struct GNUNET_PeerIdentity *target,
3466 void *value)
3467{
3468 struct Queue *queue = value;
3469
3470 (void) cls;
3471 (void) target;
3472 queue_destroy (queue);
3473 return GNUNET_OK;
3474}
3475
3476
3477/**
3478 * Shutdown the UNIX communicator.
3479 *
3480 * @param cls NULL (always)
3481 */
3482static void
3483do_shutdown (void *cls)
3484{
3485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3486 "Shutdown %s!\n",
3487 shutdown_running ? "running" : "not running");
3488
3489 if (GNUNET_YES == shutdown_running)
3490 return;
3491 else
3492 shutdown_running = GNUNET_YES;
3493
3494 while (NULL != proto_head)
3495 free_proto_queue (proto_head);
3496 if (NULL != nat)
3497 {
3498 GNUNET_NAT_unregister (nat);
3499 nat = NULL;
3500 }
3501 GNUNET_CONTAINER_multihashmap_iterate (pending_reversals,
3502 &pending_reversals_delete_it, NULL);
3503 GNUNET_CONTAINER_multihashmap_destroy (pending_reversals);
3504 GNUNET_CONTAINER_multihashmap_iterate (lt_map, &get_lt_delete_it, NULL);
3505 GNUNET_CONTAINER_multihashmap_destroy (lt_map);
3506 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL);
3507 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
3508 if (NULL != ch)
3509 {
3510 GNUNET_TRANSPORT_communicator_address_remove_all (ch);
3511 GNUNET_TRANSPORT_communicator_disconnect (ch);
3512 ch = NULL;
3513 }
3514 if (NULL != stats)
3515 {
3516 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
3517 stats = NULL;
3518 }
3519 if (NULL != my_private_key)
3520 {
3521 GNUNET_free (my_private_key);
3522 my_private_key = NULL;
3523 }
3524 if (NULL != is)
3525 {
3526 GNUNET_NT_scanner_done (is);
3527 is = NULL;
3528 }
3529 if (NULL != peerstore)
3530 {
3531 GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO);
3532 peerstore = NULL;
3533 }
3534 if (NULL != resolve_request_handle)
3535 {
3536 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3537 resolve_request_handle = NULL;
3538 }
3539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3540 "Shutdown done!\n");
3541}
3542
3543
3544/**
3545 * Function called when the transport service has received an
3546 * acknowledgement for this communicator (!) via a different return
3547 * path.
3548 *
3549 * Not applicable for TCP.
3550 *
3551 * @param cls closure
3552 * @param sender which peer sent the notification
3553 * @param msg payload
3554 */
3555static void
3556enc_notify_cb (void *cls,
3557 const struct GNUNET_PeerIdentity *sender,
3558 const struct GNUNET_MessageHeader *msg)
3559{
3560 (void) cls;
3561 (void) sender;
3562 (void) msg;
3563 GNUNET_break_op (0);
3564}
3565
3566
3567/**
3568 * Signature of the callback passed to #GNUNET_NAT_register() for
3569 * a function to call whenever our set of 'valid' addresses changes.
3570 *
3571 * @param cls closure
3572 * @param[in,out] app_ctx location where the app can store stuff
3573 * on add and retrieve it on remove
3574 * @param add_remove #GNUNET_YES to add a new public IP address,
3575 * #GNUNET_NO to remove a previous (now invalid) one
3576 * @param ac address class the address belongs to
3577 * @param addr either the previous or the new public IP address
3578 * @param addrlen actual length of the @a addr
3579 */
3580static void
3581nat_address_cb (void *cls,
3582 void **app_ctx,
3583 int add_remove,
3584 enum GNUNET_NAT_AddressClass ac,
3585 const struct sockaddr *addr,
3586 socklen_t addrlen)
3587{
3588 char *my_addr;
3589 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
3590
3591 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3592 "nat address cb %s %s\n",
3593 add_remove ? "add" : "remove",
3594 GNUNET_a2s (addr, addrlen));
3595
3596 if (GNUNET_YES == add_remove)
3597 {
3598 enum GNUNET_NetworkType nt;
3599
3600 GNUNET_asprintf (&my_addr,
3601 "%s-%s",
3602 COMMUNICATOR_ADDRESS_PREFIX,
3603 GNUNET_a2s (addr, addrlen));
3604 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3605 ai =
3606 GNUNET_TRANSPORT_communicator_address_add (ch,
3607 my_addr,
3608 nt,
3609 GNUNET_TIME_UNIT_FOREVER_REL);
3610 GNUNET_free (my_addr);
3611 *app_ctx = ai;
3612 }
3613 else
3614 {
3615 ai = *app_ctx;
3616 GNUNET_TRANSPORT_communicator_address_remove (ai);
3617 *app_ctx = NULL;
3618 }
3619}
3620
3621
3622/**
3623 * This method adds addresses to the DLL, that are later register at the NAT service.
3624 */
3625static void
3626add_addr (struct sockaddr *in, socklen_t in_len)
3627{
3628
3629 struct Addresses *saddrs;
3630
3631 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3632 "add address %s\n",
3633 GNUNET_a2s (in, in_len));
3634
3635 saddrs = GNUNET_new (struct Addresses);
3636 saddrs->addr = in;
3637 saddrs->addr_len = in_len;
3638 GNUNET_CONTAINER_DLL_insert (addrs_head, addrs_tail, saddrs);
3639
3640 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3641 "after add address %s\n",
3642 GNUNET_a2s (in, in_len));
3643
3644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3645 "add address %s\n",
3646 GNUNET_a2s (saddrs->addr, saddrs->addr_len));
3647
3648 addrs_lens++;
3649}
3650
3651
3652/**
3653 * This method launch network interactions for each address we like to bind to.
3654 *
3655 * @param addr The address we will listen to.
3656 * @param in_len The length of the address we will listen to.
3657 * @return GNUNET_SYSERR in case of error. GNUNET_OK in case we are successfully listen to the address.
3658 */
3659static int
3660init_socket (struct sockaddr *addr,
3661 socklen_t in_len)
3662{
3663 struct sockaddr_storage in_sto;
3664 socklen_t sto_len;
3665 struct GNUNET_NETWORK_Handle *listen_sock;
3666 struct ListenTask *lt;
3667 int sockfd;
3668 struct GNUNET_HashCode h_sock;
3669
3670 if (NULL == addr)
3671 {
3672 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3673 "Address is NULL.\n");
3674 return GNUNET_SYSERR;
3675 }
3676
3677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3678 "address %s\n",
3679 GNUNET_a2s (addr, in_len));
3680
3681 listen_sock =
3682 GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3683 if (NULL == listen_sock)
3684 {
3685 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
3686 return GNUNET_SYSERR;
3687 }
3688
3689 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3690 {
3691 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
3692 GNUNET_NETWORK_socket_close (listen_sock);
3693 listen_sock = NULL;
3694 return GNUNET_SYSERR;
3695 }
3696
3697 if (GNUNET_OK !=
3698 GNUNET_NETWORK_socket_listen (listen_sock,
3699 5))
3700 {
3701 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3702 "listen");
3703 GNUNET_NETWORK_socket_close (listen_sock);
3704 listen_sock = NULL;
3705 return GNUNET_SYSERR;
3706 }
3707
3708 /* We might have bound to port 0, allowing the OS to figure it out;
3709 thus, get the real IN-address from the socket */
3710 sto_len = sizeof(in_sto);
3711
3712 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3713 (struct sockaddr *) &in_sto,
3714 &sto_len))
3715 {
3716 memcpy (&in_sto, addr, in_len);
3717 sto_len = in_len;
3718 }
3719
3720 // addr = (struct sockaddr *) &in_sto;
3721 in_len = sto_len;
3722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3723 "Bound to `%s'\n",
3724 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3725 stats = GNUNET_STATISTICS_create ("C-TCP", cfg);
3726
3727 if (NULL == is)
3728 is = GNUNET_NT_scanner_init ();
3729
3730 if (NULL == my_private_key)
3731 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
3732 if (NULL == my_private_key)
3733 {
3734 GNUNET_log (
3735 GNUNET_ERROR_TYPE_ERROR,
3736 _ (
3737 "Transport service is lacking key configuration settings. Exiting.\n"));
3738 if (NULL != resolve_request_handle)
3739 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3740 GNUNET_SCHEDULER_shutdown ();
3741 return GNUNET_SYSERR;
3742 }
3743 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key);
3744 /* start listening */
3745
3746 lt = GNUNET_new (struct ListenTask);
3747 lt->listen_sock = listen_sock;
3748
3749 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3750 listen_sock,
3751 &listen_cb,
3752 lt);
3753
3754 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3755 "creating hash\n");
3756 sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3757 GNUNET_CRYPTO_hash (&sockfd,
3758 sizeof(int),
3759 &h_sock);
3760
3761 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3762 "creating map\n");
3763 if (NULL == lt_map)
3764 lt_map = GNUNET_CONTAINER_multihashmap_create (2, GNUNET_NO);
3765
3766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3767 "creating map entry\n");
3768 GNUNET_assert (GNUNET_OK ==
3769 GNUNET_CONTAINER_multihashmap_put (lt_map,
3770 &h_sock,
3771 lt,
3772 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3773
3774 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3775 "map entry created\n");
3776
3777 if (NULL == queue_map)
3778 queue_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
3779
3780 if (NULL == ch)
3781 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
3782 COMMUNICATOR_CONFIG_SECTION,
3783 COMMUNICATOR_ADDRESS_PREFIX,
3784 GNUNET_TRANSPORT_CC_RELIABLE,
3785 &mq_init,
3786 NULL,
3787 &enc_notify_cb,
3788 NULL);
3789
3790 if (NULL == ch)
3791 {
3792 GNUNET_break (0);
3793 if (NULL != resolve_request_handle)
3794 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3795 GNUNET_SCHEDULER_shutdown ();
3796 return GNUNET_SYSERR;
3797 }
3798
3799 add_addr (addr, in_len);
3800 return GNUNET_OK;
3801
3802}
3803
3804
3805/**
3806 * This method reads from the DLL addrs_head to register them at the NAT service.
3807 */
3808static void
3809nat_register ()
3810{
3811 struct sockaddr **saddrs;
3812 socklen_t *saddr_lens;
3813 int i;
3814 size_t len;
3815
3816 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3817 "starting nat register!\n");
3818 len = 0;
3819 i = 0;
3820 saddrs = GNUNET_malloc ((addrs_lens) * sizeof(struct sockaddr *));
3821 saddr_lens = GNUNET_malloc ((addrs_lens) * sizeof(socklen_t));
3822 for (struct Addresses *pos = addrs_head; NULL != pos; pos = pos->next)
3823 {
3824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3825 "registering address %s\n",
3826 GNUNET_a2s (addrs_head->addr, addrs_head->addr_len));
3827
3828 saddr_lens[i] = addrs_head->addr_len;
3829 len += saddr_lens[i];
3830 saddrs[i] = GNUNET_memdup (addrs_head->addr, saddr_lens[i]);
3831 i++;
3832 }
3833
3834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3835 "registering addresses %lu %lu %lu %lu\n",
3836 (addrs_lens) * sizeof(struct sockaddr *),
3837 (addrs_lens) * sizeof(socklen_t),
3838 len,
3839 sizeof(COMMUNICATOR_CONFIG_SECTION));
3840 nat = GNUNET_NAT_register (cfg,
3841 COMMUNICATOR_CONFIG_SECTION,
3842 IPPROTO_TCP,
3843 addrs_lens,
3844 (const struct sockaddr **) saddrs,
3845 saddr_lens,
3846 &nat_address_cb,
3847 try_connection_reversal,
3848 NULL /* closure */);
3849 for (i = addrs_lens - 1; i >= 0; i--)
3850 GNUNET_free (saddrs[i]);
3851 GNUNET_free (saddrs);
3852 GNUNET_free (saddr_lens);
3853
3854 if (NULL == nat)
3855 {
3856 GNUNET_break (0);
3857 if (NULL != resolve_request_handle)
3858 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3859 GNUNET_SCHEDULER_shutdown ();
3860 }
3861}
3862
3863
3864/**
3865 * This method is the callback called by the resolver API, and wraps method init_socket.
3866 *
3867 * @param cls The port we will bind to.
3868 * @param addr The address we will bind to.
3869 * @param in_len The length of the address we will bind to.
3870 */
3871static void
3872init_socket_resolv (void *cls,
3873 const struct sockaddr *addr,
3874 socklen_t in_len)
3875{
3876 struct sockaddr_in *v4;
3877 struct sockaddr_in6 *v6;
3878 struct sockaddr *in;
3879
3880 (void) cls;
3881 if (NULL != addr)
3882 {
3883 if (AF_INET == addr->sa_family)
3884 {
3885 v4 = (struct sockaddr_in *) addr;
3886 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, bind_port);// _global);
3887 }
3888 else if (AF_INET6 == addr->sa_family)
3889 {
3890 v6 = (struct sockaddr_in6 *) addr;
3891 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, bind_port);// _global);
3892 }
3893 else
3894 {
3895 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3896 "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
3897 addr->sa_family,
3898 AF_INET,
3899 AF_INET6);
3900 return;
3901 }
3902 init_socket (in, in_len);
3903 }
3904 else
3905 {
3906 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3907 "Address is NULL. This might be an error or the resolver finished resolving.\n");
3908 if (NULL == addrs_head)
3909 {
3910 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3911 "Resolver finished resolving, but we do not listen to an address!.\n");
3912 return;
3913 }
3914 nat_register ();
3915 }
3916}
3917
3918
3919/**
3920 * Setup communicator and launch network interactions.
3921 *
3922 * @param cls NULL (always)
3923 * @param args remaining command-line arguments
3924 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
3925 * @param c configuration
3926 */
3927static void
3928run (void *cls,
3929 char *const *args,
3930 const char *cfgfile,
3931 const struct GNUNET_CONFIGURATION_Handle *c)
3932{
3933 char *bindto;
3934 struct sockaddr *in;
3935 socklen_t in_len;
3936 struct sockaddr_in v4;
3937 struct sockaddr_in6 v6;
3938 char *start;
3939 unsigned int port;
3940 char dummy[2];
3941 char *rest = NULL;
3942 struct PortOnlyIpv4Ipv6 *po;
3943 socklen_t addr_len_ipv4;
3944 socklen_t addr_len_ipv6;
3945
3946 (void) cls;
3947
3948 pending_reversals = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
3949 memset (&v4,0,sizeof(struct sockaddr_in));
3950 memset (&v6,0,sizeof(struct sockaddr_in6));
3951 cfg = c;
3952 if (GNUNET_OK !=
3953 GNUNET_CONFIGURATION_get_value_string (cfg,
3954 COMMUNICATOR_CONFIG_SECTION,
3955 "BINDTO",
3956 &bindto))
3957 {
3958 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
3959 COMMUNICATOR_CONFIG_SECTION,
3960 "BINDTO");
3961 return;
3962 }
3963 if (GNUNET_OK !=
3964 GNUNET_CONFIGURATION_get_value_number (cfg,
3965 COMMUNICATOR_CONFIG_SECTION,
3966 "MAX_QUEUE_LENGTH",
3967 &max_queue_length))
3968 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
3969 if (GNUNET_OK !=
3970 GNUNET_CONFIGURATION_get_value_time (cfg,
3971 COMMUNICATOR_CONFIG_SECTION,
3972 "REKEY_INTERVAL",
3973 &rekey_interval))
3974 rekey_interval = DEFAULT_REKEY_INTERVAL;
3975
3976 peerstore = GNUNET_PEERSTORE_connect (cfg);
3977 if (NULL == peerstore)
3978 {
3979 GNUNET_free (bindto);
3980 GNUNET_break (0);
3981 GNUNET_SCHEDULER_shutdown ();
3982 return;
3983 }
3984
3985 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
3986
3987 if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
3988 {
3989 po = tcp_address_to_sockaddr_port_only (bindto, &bind_port);
3990 addr_len_ipv4 = po->addr_len_ipv4;
3991 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3992 "address po %s\n",
3993 GNUNET_a2s (po->addr_ipv4, addr_len_ipv4));
3994 if (NULL != po->addr_ipv4)
3995 {
3996 init_socket (po->addr_ipv4, addr_len_ipv4);
3997 }
3998 if (NULL != po->addr_ipv6)
3999 {
4000 addr_len_ipv6 = po->addr_len_ipv6;
4001 init_socket (po->addr_ipv6, addr_len_ipv6);
4002 }
4003 GNUNET_free (po);
4004 nat_register ();
4005 GNUNET_free (bindto);
4006 return;
4007 }
4008
4009 start = extract_address (bindto);
4010 // FIXME: check for NULL == start...
4011 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
4012 {
4013 bind_port = extract_port (bindto);
4014
4015 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, v4, bind_port);
4016 init_socket (in, in_len);
4017 nat_register ();
4018 GNUNET_free (start);
4019 GNUNET_free (bindto);
4020 return;
4021 }
4022
4023 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
4024 {
4025 bind_port = extract_port (bindto);
4026 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, v6, bind_port);
4027 init_socket (in, in_len);
4028 nat_register ();
4029 GNUNET_free (start);
4030 GNUNET_free (bindto);
4031 return;
4032 }
4033
4034 bind_port = extract_port (bindto);
4035 resolve_request_handle = GNUNET_RESOLVER_ip_get (strtok_r (bindto,
4036 ":",
4037 &rest),
4038 AF_UNSPEC,
4039 GNUNET_TIME_UNIT_MINUTES,
4040 &init_socket_resolv,
4041 &port);
4042
4043 GNUNET_free (bindto);
4044 GNUNET_free (start);
4045}
4046
4047
4048/**
4049 * The main function for the UNIX communicator.
4050 *
4051 * @param argc number of arguments from the command line
4052 * @param argv command line arguments
4053 * @return 0 ok, 1 on error
4054 */
4055int
4056main (int argc, char *const *argv)
4057{
4058 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4059 GNUNET_GETOPT_OPTION_END
4060 };
4061 int ret;
4062
4063 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4064 "Starting tcp communicator\n");
4065 if (GNUNET_OK !=
4066 GNUNET_STRINGS_get_utf8_args (argc, argv,
4067 &argc, &argv))
4068 return 2;
4069
4070 ret = (GNUNET_OK ==
4071 GNUNET_PROGRAM_run (argc,
4072 argv,
4073 "gnunet-communicator-tcp",
4074 _ ("GNUnet TCP communicator"),
4075 options,
4076 &run,
4077 NULL))
4078 ? 0
4079 : 1;
4080 GNUNET_free_nz ((void *) argv);
4081 return ret;
4082}
4083
4084
4085/* end of gnunet-communicator-tcp.c */