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