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