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