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.c3686
1 files changed, 0 insertions, 3686 deletions
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
deleted file mode 100644
index 6d7a151ec..000000000
--- a/src/transport/gnunet-communicator-tcp.c
+++ /dev/null
@@ -1,3686 +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_PURPOSE_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 GNUNET_CRYPTO_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_PURPOSE_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 GNUNET_CRYPTO_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_PURPOSE_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 GNUNET_CRYPTO_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_PURPOSE_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 GNUNET_CRYPTO_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_PURPOSE_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_PURPOSE_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 GNUNET_CRYPTO_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 GNUNET_CRYPTO_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 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1123 "pass message from %s to core\n",
1124 GNUNET_i2s (&queue->target));
1125
1126 if (ntohs (hdr->size) != plaintext_len)
1127 {
1128 /* NOTE: If we ever allow multiple CORE messages in one
1129 BOX, this will have to change! */
1130 GNUNET_break (0);
1131 return;
1132 }
1133 ret = GNUNET_TRANSPORT_communicator_receive (ch,
1134 &queue->target,
1135 hdr,
1136 ADDRESS_VALIDITY_PERIOD,
1137 &core_read_finished_cb,
1138 queue);
1139 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1140 "passed to core\n");
1141 if (GNUNET_OK == ret)
1142 queue->backpressure++;
1143 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
1144 if (GNUNET_SYSERR == ret)
1145 GNUNET_STATISTICS_update (stats,
1146 "# bytes lost due to CORE not running",
1147 plaintext_len,
1148 GNUNET_NO);
1149}
1150
1151
1152/**
1153 * Setup @a cipher based on shared secret @a dh and decrypting
1154 * peer @a pid.
1155 *
1156 * @param dh shared secret
1157 * @param pid decrypting peer's identity
1158 * @param cipher[out] cipher to initialize
1159 * @param hmac_key[out] HMAC key to initialize
1160 */
1161static void
1162setup_cipher (const struct GNUNET_HashCode *dh,
1163 const struct GNUNET_PeerIdentity *pid,
1164 gcry_cipher_hd_t *cipher,
1165 struct GNUNET_HashCode *hmac_key)
1166{
1167 char key[256 / 8];
1168 char ctr[128 / 8];
1169
1170 GNUNET_assert (0 == gcry_cipher_open (cipher,
1171 GCRY_CIPHER_AES256 /* low level: go for speed */,
1172 GCRY_CIPHER_MODE_CTR,
1173 0 /* flags */));
1174 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (key,
1175 sizeof(key),
1176 "TCP-key",
1177 strlen ("TCP-key"),
1178 dh,
1179 sizeof(*dh),
1180 pid,
1181 sizeof(*pid),
1182 NULL,
1183 0));
1184 GNUNET_assert (0 == gcry_cipher_setkey (*cipher, key, sizeof(key)));
1185 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (ctr,
1186 sizeof(ctr),
1187 "TCP-ctr",
1188 strlen ("TCP-ctr"),
1189 dh,
1190 sizeof(*dh),
1191 pid,
1192 sizeof(*pid),
1193 NULL,
1194 0));
1195 gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
1196 GNUNET_assert (GNUNET_YES ==
1197 GNUNET_CRYPTO_kdf (hmac_key,
1198 sizeof(struct GNUNET_HashCode),
1199 "TCP-hmac",
1200 strlen ("TCP-hmac"),
1201 dh,
1202 sizeof(*dh),
1203 pid,
1204 sizeof(*pid),
1205 NULL,
1206 0));
1207}
1208
1209
1210/**
1211 * Callback called when peerstore store operation for rekey monotime value is finished.
1212 * @param cls Queue context the store operation was executed.
1213 * @param success Store operation was successful (GNUNET_OK) or not.
1214 */
1215static void
1216rekey_monotime_store_cb (void *cls, int success)
1217{
1218 struct Queue *queue = cls;
1219 if (GNUNET_OK != success)
1220 {
1221 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1222 "Failed to store rekey monotonic time in PEERSTORE!\n");
1223 }
1224 queue->rekey_monotime_sc = NULL;
1225}
1226
1227
1228/**
1229 * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY
1230 * where found.
1231 * @param cls Queue context the store operation was executed.
1232 * @param record The record found or NULL if there is no record left.
1233 * @param emsg Message from peerstore.
1234 */
1235static void
1236rekey_monotime_cb (void *cls,
1237 const struct GNUNET_PEERSTORE_Record *record,
1238 const char *emsg)
1239{
1240 struct Queue *queue = cls;
1241 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1242 struct GNUNET_TIME_Absolute mt;
1243 const struct GNUNET_PeerIdentity *pid;
1244 struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
1245
1246 (void) emsg;
1247
1248 rekey_monotonic_time = &queue->rekey_monotonic_time;
1249 pid = &queue->target;
1250 if (NULL == record)
1251 {
1252 queue->rekey_monotime_get = NULL;
1253 return;
1254 }
1255 if (sizeof(*mtbe) != record->value_size)
1256 {
1257 GNUNET_break (0);
1258 return;
1259 }
1260 mtbe = record->value;
1261 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1262 if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
1263 queue->rekey_monotonic_time).abs_value_us)
1264 {
1265 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1266 "Queue from %s dropped, rekey monotime in the past\n",
1267 GNUNET_i2s (&queue->target));
1268 GNUNET_break (0);
1269 queue_finish (queue);
1270 return;
1271 }
1272 queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
1273 "transport_tcp_communicator",
1274 pid,
1275 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY,
1276 rekey_monotonic_time,
1277 sizeof(*
1278 rekey_monotonic_time),
1279 GNUNET_TIME_UNIT_FOREVER_ABS,
1280 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
1281 &rekey_monotime_store_cb,
1282 queue);
1283}
1284
1285
1286/**
1287 * Setup cipher of @a queue for decryption.
1288 *
1289 * @param ephemeral ephemeral key we received from the other peer
1290 * @param queue[in,out] queue to initialize decryption cipher for
1291 */
1292static void
1293setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1294 struct Queue *queue)
1295{
1296 struct GNUNET_HashCode dh;
1297
1298 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &dh);
1299 setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac);
1300}
1301
1302
1303/**
1304 * Handle @a rekey message on @a queue. The message was already
1305 * HMAC'ed, but we should additionally still check the signature.
1306 * Then we need to stop the old cipher and start afresh.
1307 *
1308 * @param queue the queue @a rekey was received on
1309 * @param rekey the rekey message
1310 */
1311static void
1312do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
1313{
1314 struct TcpRekeySignature thp;
1315
1316 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY);
1317 thp.purpose.size = htonl (sizeof(thp));
1318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1319 "do_rekey size %u\n",
1320 thp.purpose.size);
1321 thp.sender = queue->target;
1322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1323 "sender %s\n",
1324 GNUNET_p2s (&thp.sender.public_key));
1325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1326 "sender %s\n",
1327 GNUNET_p2s (&queue->target.public_key));
1328 thp.receiver = my_identity;
1329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1330 "receiver %s\n",
1331 GNUNET_p2s (&thp.receiver.public_key));
1332 thp.ephemeral = rekey->ephemeral;
1333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1334 "ephemeral %s\n",
1335 GNUNET_e2s (&thp.ephemeral));
1336 thp.monotonic_time = rekey->monotonic_time;
1337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1338 "time %s\n",
1339 GNUNET_STRINGS_absolute_time_to_string (
1340 GNUNET_TIME_absolute_ntoh (thp.monotonic_time)));
1341 GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp)));
1342 if (GNUNET_OK !=
1343 GNUNET_CRYPTO_eddsa_verify (
1344 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY,
1345 &thp,
1346 &rekey->sender_sig,
1347 &queue->target.public_key))
1348 {
1349 GNUNET_break (0);
1350 queue_finish (queue);
1351 return;
1352 }
1353 queue->rekey_monotonic_time = rekey->monotonic_time;
1354 queue->rekey_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1355 "transport_tcp_communicator",
1356 &queue->target,
1357 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY,
1358 &rekey_monotime_cb,
1359 queue);
1360 gcry_cipher_close (queue->in_cipher);
1361 queue->rekeyed = GNUNET_YES;
1362 setup_in_cipher (&rekey->ephemeral, queue);
1363}
1364
1365
1366/**
1367 * Callback called when peerstore store operation for handshake ack monotime value is finished.
1368 * @param cls Queue context the store operation was executed.
1369 * @param success Store operation was successful (GNUNET_OK) or not.
1370 */
1371static void
1372handshake_ack_monotime_store_cb (void *cls, int success)
1373{
1374 struct Queue *queue = cls;
1375
1376 if (GNUNET_OK != success)
1377 {
1378 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1379 "Failed to store handshake ack monotonic time in PEERSTORE!\n");
1380 }
1381 queue->handshake_ack_monotime_sc = NULL;
1382}
1383
1384
1385/**
1386 * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK
1387 * where found.
1388 * @param cls Queue context the store operation was executed.
1389 * @param record The record found or NULL if there is no record left.
1390 * @param emsg Message from peerstore.
1391 */
1392static void
1393handshake_ack_monotime_cb (void *cls,
1394 const struct GNUNET_PEERSTORE_Record *record,
1395 const char *emsg)
1396{
1397 struct Queue *queue = cls;
1398 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1399 struct GNUNET_TIME_Absolute mt;
1400 const struct GNUNET_PeerIdentity *pid;
1401 struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
1402
1403 (void) emsg;
1404
1405 handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
1406 pid = &queue->target;
1407 if (NULL == record)
1408 {
1409 queue->handshake_ack_monotime_get = NULL;
1410 return;
1411 }
1412 if (sizeof(*mtbe) != record->value_size)
1413 {
1414 GNUNET_break (0);
1415 return;
1416 }
1417 mtbe = record->value;
1418 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1419 if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
1420 queue->handshake_ack_monotonic_time).abs_value_us)
1421 {
1422 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1423 "Queue from %s dropped, handshake ack monotime in the past\n",
1424 GNUNET_i2s (&queue->target));
1425 GNUNET_break (0);
1426 queue_finish (queue);
1427 return;
1428 }
1429 queue->handshake_ack_monotime_sc =
1430 GNUNET_PEERSTORE_store (peerstore,
1431 "transport_tcp_communicator",
1432 pid,
1433 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK,
1434 handshake_ack_monotonic_time,
1435 sizeof(*handshake_ack_monotonic_time),
1436 GNUNET_TIME_UNIT_FOREVER_ABS,
1437 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
1438 &
1439 handshake_ack_monotime_store_cb,
1440 queue);
1441}
1442
1443
1444/**
1445 * Sending challenge with TcpConfirmationAck back to sender of ephemeral key.
1446 *
1447 * @param tc The TCPConfirmation originally send.
1448 * @param queue The queue context.
1449 */
1450static void
1451send_challenge (struct GNUNET_CRYPTO_ChallengeNonceP challenge, struct
1452 Queue *queue)
1453{
1454 struct TCPConfirmationAck tca;
1455 struct TcpHandshakeAckSignature thas;
1456
1457 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
1458 "transport",
1459 "sending challenge\n");
1460
1461 tca.header.type = ntohs (
1462 GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK);
1463 tca.header.size = ntohs (sizeof(tca));
1464 tca.challenge = challenge;
1465 tca.sender = my_identity;
1466 tca.monotonic_time =
1467 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1468 thas.purpose.purpose = htonl (
1469 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK);
1470 thas.purpose.size = htonl (sizeof(thas));
1471 thas.sender = my_identity;
1472 thas.receiver = queue->target;
1473 thas.monotonic_time = tca.monotonic_time;
1474 thas.challenge = tca.challenge;
1475 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1476 &thas,
1477 &tca.sender_sig);
1478 GNUNET_assert (0 ==
1479 gcry_cipher_encrypt (queue->out_cipher,
1480 &queue->cwrite_buf[queue->cwrite_off],
1481 sizeof(tca),
1482 &tca,
1483 sizeof(tca)));
1484 queue->cwrite_off += sizeof(tca);
1485 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
1486 "transport",
1487 "sending challenge done\n");
1488}
1489
1490
1491/**
1492 * Setup cipher for outgoing data stream based on target and
1493 * our ephemeral private key.
1494 *
1495 * @param queue queue to setup outgoing (encryption) cipher for
1496 */
1497static void
1498setup_out_cipher (struct Queue *queue)
1499{
1500 struct GNUNET_HashCode dh;
1501
1502 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral, &queue->target.public_key, &dh);
1503 /* we don't need the private key anymore, drop it! */
1504 memset (&queue->ephemeral, 0, sizeof(queue->ephemeral));
1505 setup_cipher (&dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1506 queue->rekey_time = GNUNET_TIME_relative_to_absolute (rekey_interval);
1507 queue->rekey_left_bytes =
1508 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, REKEY_MAX_BYTES);
1509}
1510
1511
1512/**
1513 * Inject a `struct TCPRekey` message into the queue's plaintext
1514 * buffer.
1515 *
1516 * @param queue queue to perform rekeying on
1517 */
1518static void
1519inject_rekey (struct Queue *queue)
1520{
1521 struct TCPRekey rekey;
1522 struct TcpRekeySignature thp;
1523
1524 GNUNET_assert (0 == queue->pwrite_off);
1525 memset (&rekey, 0, sizeof(rekey));
1526 GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
1527 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1528 rekey.header.size = ntohs (sizeof(rekey));
1529 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral);
1530 rekey.monotonic_time =
1531 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1532 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY);
1533 thp.purpose.size = htonl (sizeof(thp));
1534 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1535 "inject_rekey size %u\n",
1536 thp.purpose.size);
1537 thp.sender = my_identity;
1538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1539 "sender %s\n",
1540 GNUNET_p2s (&thp.sender.public_key));
1541 thp.receiver = queue->target;
1542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1543 "receiver %s\n",
1544 GNUNET_p2s (&thp.receiver.public_key));
1545 thp.ephemeral = rekey.ephemeral;
1546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1547 "ephemeral %s\n",
1548 GNUNET_e2s (&thp.ephemeral));
1549 thp.monotonic_time = rekey.monotonic_time;
1550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1551 "time %s\n",
1552 GNUNET_STRINGS_absolute_time_to_string (
1553 GNUNET_TIME_absolute_ntoh (thp.monotonic_time)));
1554 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1555 &thp,
1556 &rekey.sender_sig);
1557 calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1558 /* Encrypt rekey message with 'old' cipher */
1559 GNUNET_assert (0 ==
1560 gcry_cipher_encrypt (queue->out_cipher,
1561 &queue->cwrite_buf[queue->cwrite_off],
1562 sizeof(rekey),
1563 &rekey,
1564 sizeof(rekey)));
1565 queue->cwrite_off += sizeof(rekey);
1566 /* Setup new cipher for successive messages */
1567 gcry_cipher_close (queue->out_cipher);
1568 setup_out_cipher (queue);
1569}
1570
1571
1572/**
1573 * We have been notified that our socket is ready to write.
1574 * Then reschedule this function to be called again once more is available.
1575 *
1576 * @param cls a `struct Queue`
1577 */
1578static void
1579queue_write (void *cls)
1580{
1581 struct Queue *queue = cls;
1582 ssize_t sent;
1583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1584 queue->write_task = NULL;
1585 if (0 != queue->cwrite_off)
1586 {
1587 sent = GNUNET_NETWORK_socket_send (queue->sock,
1588 queue->cwrite_buf,
1589 queue->cwrite_off);
1590 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1591 "Sent %lu bytes to TCP queue\n", sent);
1592 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1593 {
1594 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
1595 queue_destroy (queue);
1596 return;
1597 }
1598 if (sent > 0)
1599 {
1600 size_t usent = (size_t) sent;
1601 queue->cwrite_off -= usent;
1602 memmove (queue->cwrite_buf,
1603 &queue->cwrite_buf[usent],
1604 queue->cwrite_off);
1605 reschedule_queue_timeout (queue);
1606 }
1607 }
1608 /* can we encrypt more? (always encrypt full messages, needed
1609 such that #mq_cancel() can work!) */
1610 if ((0 < queue->rekey_left_bytes) &&
1611 (queue->pwrite_off > 0) &&
1612 (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1613 {
1614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1615 "Encrypting %lu bytes\n", queue->pwrite_off);
1616 GNUNET_assert (0 ==
1617 gcry_cipher_encrypt (queue->out_cipher,
1618 &queue->cwrite_buf[queue->cwrite_off],
1619 queue->pwrite_off,
1620 queue->pwrite_buf,
1621 queue->pwrite_off));
1622 if (queue->rekey_left_bytes > queue->pwrite_off)
1623 queue->rekey_left_bytes -= queue->pwrite_off;
1624 else
1625 queue->rekey_left_bytes = 0;
1626 queue->cwrite_off += queue->pwrite_off;
1627 queue->pwrite_off = 0;
1628 }
1629 // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1630 if (((0 == queue->pwrite_off) &&
1631 ((0 == queue->rekey_left_bytes) ||
1632 (0 ==
1633 GNUNET_TIME_absolute_get_remaining (
1634 queue->rekey_time).rel_value_us))))
1635 {
1636 inject_rekey (queue);
1637 }
1638 if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1639 (GNUNET_YES == queue->mq_awaits_continue))
1640 {
1641 queue->mq_awaits_continue = GNUNET_NO;
1642 GNUNET_MQ_impl_send_continue (queue->mq);
1643 }
1644 /* did we just finish writing 'finish'? */
1645 if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1646 {
1647 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1648 "Finishing queue\n");
1649 queue_destroy (queue);
1650 return;
1651 }
1652 /* do we care to write more? */
1653 if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1654 queue->write_task =
1655 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1656 queue->sock,
1657 &queue_write,
1658 queue);
1659}
1660
1661
1662/**
1663 * Test if we have received a full message in plaintext.
1664 * If so, handle it.
1665 *
1666 * @param queue queue to process inbound plaintext for
1667 * @return number of bytes of plaintext handled, 0 for none
1668 */
1669static size_t
1670try_handle_plaintext (struct Queue *queue)
1671{
1672 const struct GNUNET_MessageHeader *hdr =
1673 (const struct GNUNET_MessageHeader *) queue->pread_buf;
1674 const struct TCPConfirmationAck *tca = (const struct
1675 TCPConfirmationAck *) queue->pread_buf;
1676 const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf;
1677 const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf;
1678 const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf;
1679 struct TCPRekey rekeyz;
1680 struct TCPFinish finz;
1681 struct GNUNET_ShortHashCode tmac;
1682 uint16_t type;
1683 size_t size = 0; /* make compiler happy */
1684 struct TcpHandshakeAckSignature thas;
1685 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1686
1687 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1688 "try handle plaintext!\n");
1689
1690 if ((sizeof(*hdr) > queue->pread_off))
1691 {
1692 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1693 "Handling plaintext, not even a header!\n");
1694 return 0; /* not even a header */
1695 }
1696
1697 if ((-1 != unverified_size) && (unverified_size > INITIAL_CORE_KX_SIZE))
1698 {
1699 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1700 "Already received data of size %lu bigger than KX size %lu!\n",
1701 unverified_size,
1702 INITIAL_CORE_KX_SIZE);
1703 GNUNET_break_op (0);
1704 queue_finish (queue);
1705 return 0;
1706 }
1707
1708 type = ntohs (hdr->type);
1709 switch (type)
1710 {
1711 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK:
1712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1713 "start processing ack\n");
1714 if (sizeof(*tca) > queue->pread_off)
1715 {
1716 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1717 "Handling plaintext size of tca greater than pread offset.\n");
1718 return 0;
1719 }
1720 if (ntohs (hdr->size) != sizeof(*tca))
1721 {
1722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1723 "Handling plaintext size does not match message type.\n");
1724 GNUNET_break_op (0);
1725 queue_finish (queue);
1726 return 0;
1727 }
1728
1729 thas.purpose.purpose = htonl (
1730 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK);
1731 thas.purpose.size = htonl (sizeof(thas));
1732 thas.sender = tca->sender;
1733 thas.receiver = my_identity;
1734 thas.monotonic_time = tca->monotonic_time;
1735 thas.challenge = tca->challenge;
1736
1737 if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_verify (
1738 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK,
1739 &thas,
1740 &tca->sender_sig,
1741 &tca->sender.public_key))
1742 {
1743 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1744 "Verification of signature failed!\n");
1745 GNUNET_break (0);
1746 queue_finish (queue);
1747 return 0;
1748 }
1749 if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
1750 {
1751 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1752 "Challenge in TCPConfirmationAck not correct!\n");
1753 GNUNET_break (0);
1754 queue_finish (queue);
1755 return 0;
1756 }
1757
1758 queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1759 "transport_tcp_communicator",
1760 &queue->target,
1761 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK,
1762 &
1763 handshake_ack_monotime_cb,
1764 queue);
1765
1766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1767 "Handling plaintext, ack processed!\n");
1768
1769 if (GNUNET_TRANSPORT_CS_INBOUND == queue->cs)
1770 {
1771 send_challenge (queue->challenge_received, queue);
1772 queue->write_task =
1773 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1774 queue->sock,
1775 &queue_write,
1776 queue);
1777 }
1778
1779 unverified_size = -1;
1780
1781 char *foreign_addr;
1782
1783 switch (queue->address->sa_family)
1784 {
1785 case AF_INET:
1786 GNUNET_asprintf (&foreign_addr,
1787 "%s-%s",
1788 COMMUNICATOR_ADDRESS_PREFIX,
1789 GNUNET_a2s (queue->address, queue->address_len));
1790 break;
1791
1792 case AF_INET6:
1793 GNUNET_asprintf (&foreign_addr,
1794 "%s-%s",
1795 COMMUNICATOR_ADDRESS_PREFIX,
1796 GNUNET_a2s (queue->address, queue->address_len));
1797 break;
1798
1799 default:
1800 GNUNET_assert (0);
1801 }
1802
1803 queue->qh = GNUNET_TRANSPORT_communicator_mq_add (ch,
1804 &queue->target,
1805 foreign_addr,
1806 UINT16_MAX, /* no MTU */
1807 GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED,
1808 0, /* Priority */
1809 queue->nt,
1810 queue->cs,
1811 queue->mq);
1812
1813 GNUNET_free (foreign_addr);
1814
1815 size = ntohs (hdr->size);
1816 break;
1817 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
1818 /* Special case: header size excludes box itself! */
1819 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
1820 return 0;
1821 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
1822 if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
1823 {
1824 GNUNET_break_op (0);
1825 queue_finish (queue);
1826 return 0;
1827 }
1828 pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
1829 size = ntohs (hdr->size) + sizeof(*box);
1830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1831 "Handling plaintext, box processed!\n");
1832 break;
1833
1834 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
1835 if (sizeof(*rekey) > queue->pread_off)
1836 return 0;
1837 if (ntohs (hdr->size) != sizeof(*rekey))
1838 {
1839 GNUNET_break_op (0);
1840 queue_finish (queue);
1841 return 0;
1842 }
1843 rekeyz = *rekey;
1844 memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
1845 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
1846 if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
1847 {
1848 GNUNET_break_op (0);
1849 queue_finish (queue);
1850 return 0;
1851 }
1852 do_rekey (queue, rekey);
1853 size = ntohs (hdr->size);
1854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1855 "Handling plaintext, rekey processed!\n");
1856 break;
1857
1858 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
1859 if (sizeof(*fin) > queue->pread_off)
1860 return 0;
1861 if (ntohs (hdr->size) != sizeof(*fin))
1862 {
1863 GNUNET_break_op (0);
1864 queue_finish (queue);
1865 return 0;
1866 }
1867 finz = *fin;
1868 memset (&finz.hmac, 0, sizeof(finz.hmac));
1869 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
1870 if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
1871 {
1872 GNUNET_break_op (0);
1873 queue_finish (queue);
1874 return 0;
1875 }
1876 /* handle FINISH by destroying queue */
1877 queue_destroy (queue);
1878 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1879 "Handling plaintext, finish processed!\n");
1880 break;
1881
1882 default:
1883 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1884 "Handling plaintext, nothing processed!\n");
1885 GNUNET_break_op (0);
1886 queue_finish (queue);
1887 return 0;
1888 }
1889 GNUNET_assert (0 != size);
1890 if (-1 != unverified_size)
1891 unverified_size += size;
1892 return size;
1893}
1894
1895
1896/**
1897 * Queue read task. If we hit the timeout, disconnect it
1898 *
1899 * @param cls the `struct Queue *` to disconnect
1900 */
1901static void
1902queue_read (void *cls)
1903{
1904 struct Queue *queue = cls;
1905 struct GNUNET_TIME_Relative left;
1906 ssize_t rcvd;
1907
1908 queue->read_task = NULL;
1909 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1910 &queue->cread_buf[queue->cread_off],
1911 BUF_SIZE - queue->cread_off);
1912 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1913 "Received %lu bytes from TCP queue\n", rcvd);
1914 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
1915 "transport",
1916 "Received %lu bytes from TCP queue\n", rcvd);
1917 if (-1 == rcvd)
1918 {
1919 if ((EAGAIN != errno) && (EINTR != errno))
1920 {
1921 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
1922 queue_finish (queue);
1923 return;
1924 }
1925 /* try again */
1926 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1927 queue->read_task =
1928 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
1929 return;
1930 }
1931 if (0 != rcvd)
1932 reschedule_queue_timeout (queue);
1933 queue->cread_off += rcvd;
1934 while ((queue->pread_off < sizeof(queue->pread_buf)) &&
1935 (queue->cread_off > 0))
1936 {
1937 size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
1938 queue->cread_off);
1939 size_t done;
1940 size_t total;
1941 size_t old_pread_off = queue->pread_off;
1942
1943 GNUNET_assert (0 ==
1944 gcry_cipher_decrypt (queue->in_cipher,
1945 &queue->pread_buf[queue->pread_off],
1946 max,
1947 queue->cread_buf,
1948 max));
1949 queue->pread_off += max;
1950 total = 0;
1951 while (0 != (done = try_handle_plaintext (queue)))
1952 {
1953 /* 'done' bytes of plaintext were used, shift buffer */
1954 GNUNET_assert (done <= queue->pread_off);
1955 /* NOTE: this memmove() could possibly sometimes be
1956 avoided if we pass 'total' into try_handle_plaintext()
1957 and use it at an offset into the buffer there! */
1958 memmove (queue->pread_buf,
1959 &queue->pread_buf[done],
1960 queue->pread_off - done);
1961 queue->pread_off -= done;
1962 total += done;
1963 /* The last plaintext was a rekey, abort for now */
1964 if (GNUNET_YES == queue->rekeyed)
1965 break;
1966 }
1967 /* when we encounter a rekey message, the decryption above uses the
1968 wrong key for everything after the rekey; in that case, we have
1969 to re-do the decryption at 'total' instead of at 'max'.
1970 However, we have to take into account that the plaintext buffer may have
1971 already contained data and not jumped too far ahead in the ciphertext.
1972 If there is no rekey and the last message is incomplete (max > total),
1973 it is safe to keep the decryption so we shift by 'max' */
1974 if (GNUNET_YES == queue->rekeyed)
1975 {
1976 max = total - old_pread_off;
1977 queue->rekeyed = GNUNET_NO;
1978 queue->pread_off = 0;
1979 }
1980 memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
1981 queue->cread_off -= max;
1982 }
1983 if (BUF_SIZE == queue->cread_off)
1984 return; /* buffer full, suspend reading */
1985 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1986 if (0 != left.rel_value_us)
1987 {
1988 if (max_queue_length > queue->backpressure)
1989 {
1990 /* continue reading */
1991 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1992 queue->read_task =
1993 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
1994 }
1995 return;
1996 }
1997 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1998 "Queue %p was idle for %s, disconnecting\n",
1999 queue,
2000 GNUNET_STRINGS_relative_time_to_string (
2001 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2002 GNUNET_YES));
2003 queue_finish (queue);
2004}
2005
2006
2007/**
2008 * Convert a `struct sockaddr_in6 to a `struct sockaddr *`
2009 *
2010 * @param[out] sock_len set to the length of the address.
2011 * @param v6 The sockaddr_in6 to be converted.
2012 * @return The struct sockaddr *.
2013 */
2014static struct sockaddr *
2015tcp_address_to_sockaddr_numeric_v6 (socklen_t *sock_len,
2016 struct sockaddr_in6 v6,
2017 unsigned int port)
2018{
2019 struct sockaddr *in;
2020
2021 v6.sin6_family = AF_INET6;
2022 v6.sin6_port = htons ((uint16_t) port);
2023#if HAVE_SOCKADDR_IN_SIN_LEN
2024 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2025#endif
2026 v6.sin6_flowinfo = 0;
2027 v6.sin6_scope_id = 0;
2028 in = GNUNET_memdup (&v6, sizeof(v6));
2029 *sock_len = sizeof(struct sockaddr_in6);
2030
2031 return in;
2032}
2033
2034
2035/**
2036 * Convert a `struct sockaddr_in4 to a `struct sockaddr *`
2037 *
2038 * @param[out] sock_len set to the length of the address.
2039 * @param v4 The sockaddr_in4 to be converted.
2040 * @return The struct sockaddr *.
2041 */
2042static struct sockaddr *
2043tcp_address_to_sockaddr_numeric_v4 (socklen_t *sock_len,
2044 struct sockaddr_in v4,
2045 unsigned int port)
2046{
2047 struct sockaddr *in;
2048
2049 v4.sin_family = AF_INET;
2050 v4.sin_port = htons ((uint16_t) port);
2051#if HAVE_SOCKADDR_IN_SIN_LEN
2052 v4.sin_len = sizeof(struct sockaddr_in);
2053#endif
2054 in = GNUNET_memdup (&v4, sizeof(v4));
2055 *sock_len = sizeof(struct sockaddr_in);
2056 return in;
2057}
2058
2059
2060/**
2061 * Convert TCP bind specification to a `struct PortOnlyIpv4Ipv6 *`
2062 *
2063 * @param bindto bind specification to convert.
2064 * @return The converted bindto specification.
2065 */
2066static struct PortOnlyIpv4Ipv6 *
2067tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
2068{
2069 struct PortOnlyIpv4Ipv6 *po;
2070 struct sockaddr_in *i4;
2071 struct sockaddr_in6 *i6;
2072 socklen_t sock_len_ipv4;
2073 socklen_t sock_len_ipv6;
2074
2075 /* interpreting value as just a PORT number */
2076 if (*port > UINT16_MAX)
2077 {
2078 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2079 "BINDTO specification `%s' invalid: value too large for port\n",
2080 bindto);
2081 return NULL;
2082 }
2083
2084 po = GNUNET_new (struct PortOnlyIpv4Ipv6);
2085
2086 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2087 (GNUNET_YES ==
2088 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2089 COMMUNICATOR_CONFIG_SECTION,
2090 "DISABLE_V6")))
2091 {
2092 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2093 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2094 *port);
2095 po->addr_len_ipv4 = sock_len_ipv4;
2096 }
2097 else
2098 {
2099
2100 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2101 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2102 *port);
2103 po->addr_len_ipv4 = sock_len_ipv4;
2104
2105 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2106 po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
2107 *port);
2108
2109 po->addr_len_ipv6 = sock_len_ipv6;
2110
2111 GNUNET_free (i6);
2112 }
2113
2114 GNUNET_free (i4);
2115
2116 return po;
2117}
2118
2119
2120/**
2121 * This Method extracts the address part of the BINDTO string.
2122 *
2123 * @param bindto String we extract the address part from.
2124 * @return The extracted address string.
2125 */
2126static char *
2127extract_address (const char *bindto)
2128{
2129 char *addr;
2130 char *start;
2131 char *token;
2132 char *cp;
2133 char *rest = NULL;
2134 char *res;
2135
2136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2137 "extract address with bindto %s\n",
2138 bindto);
2139
2140 if (NULL == bindto)
2141 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2142 "bindto is NULL\n");
2143
2144 cp = GNUNET_strdup (bindto);
2145
2146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2147 "extract address 2\n");
2148
2149 start = cp;
2150 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2151 {
2152 start++; /* skip over '['*/
2153 cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
2154 addr = GNUNET_strdup (start);
2155 }
2156 else
2157 {
2158 token = strtok_r (cp, "]", &rest);
2159 if (strlen (bindto) == strlen (token))
2160 {
2161 token = strtok_r (cp, ":", &rest);
2162 addr = GNUNET_strdup (token);
2163 }
2164 else
2165 {
2166 token++;
2167 res = GNUNET_strdup (token);
2168 addr = GNUNET_strdup (res);
2169 }
2170 }
2171
2172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2173 "tcp address: %s\n",
2174 addr);
2175 GNUNET_free (cp);
2176 return addr;
2177}
2178
2179
2180/**
2181 * This Method extracts the port part of the BINDTO string.
2182 *
2183 * @param addr_and_port String we extract the port from.
2184 * @return The extracted port as unsigned int.
2185 */
2186static unsigned int
2187extract_port (const char *addr_and_port)
2188{
2189 unsigned int port;
2190 char dummy[2];
2191 char *token;
2192 char *addr;
2193 char *colon;
2194 char *cp;
2195 char *rest = NULL;
2196
2197 if (NULL != addr_and_port)
2198 {
2199 cp = GNUNET_strdup (addr_and_port);
2200 token = strtok_r (cp, "]", &rest);
2201 if (strlen (addr_and_port) == strlen (token))
2202 {
2203 colon = strrchr (cp, ':');
2204 if (NULL == colon)
2205 {
2206 GNUNET_free (cp);
2207 return 0;
2208 }
2209 addr = colon;
2210 addr++;
2211 }
2212 else
2213 {
2214 token = strtok_r (NULL, "]", &rest);
2215 if (NULL == token)
2216 {
2217 GNUNET_free (cp);
2218 return 0;
2219 }
2220 else
2221 {
2222 addr = token;
2223 addr++;
2224 }
2225 }
2226
2227
2228 if (1 == sscanf (addr, "%u%1s", &port, dummy))
2229 {
2230 /* interpreting value as just a PORT number */
2231 if (port > UINT16_MAX)
2232 {
2233 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2234 "Port `%u' invalid: value too large for port\n",
2235 port);
2236 GNUNET_free (cp);
2237 return 0;
2238 }
2239 }
2240 else
2241 {
2242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2243 "BINDTO specification invalid: last ':' not followed by number\n");
2244 GNUNET_free (cp);
2245 return 0;
2246 }
2247 GNUNET_free (cp);
2248 }
2249 else
2250 {
2251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2252 "return 0\n");
2253 /* interpret missing port as 0, aka pick any free one */
2254 port = 0;
2255 }
2256
2257 return port;
2258}
2259
2260
2261/**
2262 * Convert TCP bind specification to a `struct sockaddr *`
2263 *
2264 * @param bindto bind specification to convert
2265 * @param[out] sock_len set to the length of the address
2266 * @return converted bindto specification
2267 */
2268static struct sockaddr *
2269tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2270{
2271 struct sockaddr *in;
2272 unsigned int port;
2273 struct sockaddr_in v4;
2274 struct sockaddr_in6 v6;
2275 char *start;
2276
2277 start = extract_address (bindto);
2278 // FIXME: check NULL == start
2279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2280 "start %s\n",
2281 start);
2282
2283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2284 "!bindto %s\n",
2285 bindto);
2286
2287
2288 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2289 {
2290 // colon = strrchr (cp, ':');
2291 port = extract_port (bindto);
2292
2293 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2294 "port %u\n",
2295 port);
2296
2297 in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
2298 }
2299 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2300 {
2301 // colon = strrchr (cp, ':');
2302 port = extract_port (bindto);
2303 in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
2304 }
2305 else
2306 {
2307 GNUNET_assert (0);
2308 }
2309
2310 GNUNET_free (start);
2311 return in;
2312}
2313
2314
2315/**
2316 * Signature of functions implementing the sending functionality of a
2317 * message queue.
2318 *
2319 * @param mq the message queue
2320 * @param msg the message to send
2321 * @param impl_state our `struct Queue`
2322 */
2323static void
2324mq_send (struct GNUNET_MQ_Handle *mq,
2325 const struct GNUNET_MessageHeader *msg,
2326 void *impl_state)
2327{
2328 struct Queue *queue = impl_state;
2329 uint16_t msize = ntohs (msg->size);
2330 struct TCPBox box;
2331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2332 "In MQ send. Queue finishing: %s; write task running: %s\n",
2333 (GNUNET_YES == queue->finishing) ? "yes" : "no",
2334 (NULL == queue->write_task) ? "yes" : "no");
2335 GNUNET_assert (mq == queue->mq);
2336 queue->mq_awaits_continue = GNUNET_YES;
2337 if (GNUNET_YES == queue->finishing)
2338 return; /* this queue is dying, drop msg */
2339 GNUNET_assert (0 == queue->pwrite_off);
2340 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
2341 box.header.size = htons (msize);
2342 calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
2343 memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
2344 queue->pwrite_off += sizeof(box);
2345 memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
2346 queue->pwrite_off += msize;
2347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2348 "%lu bytes of plaintext to send\n", queue->pwrite_off);
2349 GNUNET_assert (NULL != queue->sock);
2350 if (NULL == queue->write_task)
2351 queue->write_task =
2352 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2353 queue->sock,
2354 &queue_write,
2355 queue);
2356}
2357
2358
2359/**
2360 * Signature of functions implementing the destruction of a message
2361 * queue. Implementations must not free @a mq, but should take care
2362 * of @a impl_state.
2363 *
2364 * @param mq the message queue to destroy
2365 * @param impl_state our `struct Queue`
2366 */
2367static void
2368mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
2369{
2370 struct Queue *queue = impl_state;
2371
2372 if (mq == queue->mq)
2373 {
2374 queue->mq = NULL;
2375 queue_finish (queue);
2376 }
2377}
2378
2379
2380/**
2381 * Implementation function that cancels the currently sent message.
2382 *
2383 * @param mq message queue
2384 * @param impl_state our `struct Queue`
2385 */
2386static void
2387mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2388{
2389 struct Queue *queue = impl_state;
2390
2391 GNUNET_assert (0 != queue->pwrite_off);
2392 queue->pwrite_off = 0;
2393}
2394
2395
2396/**
2397 * Generic error handler, called with the appropriate
2398 * error code and the same closure specified at the creation of
2399 * the message queue.
2400 * Not every message queue implementation supports an error handler.
2401 *
2402 * @param cls our `struct Queue`
2403 * @param error error code
2404 */
2405static void
2406mq_error (void *cls, enum GNUNET_MQ_Error error)
2407{
2408 struct Queue *queue = cls;
2409
2410 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2411 "MQ error in queue to %s: %d\n",
2412 GNUNET_i2s (&queue->target),
2413 (int) error);
2414 queue_finish (queue);
2415}
2416
2417
2418/**
2419 * Add the given @a queue to our internal data structure. Setup the
2420 * MQ processing and inform transport that the queue is ready. Must
2421 * be called after the KX for outgoing messages has been bootstrapped.
2422 *
2423 * @param queue queue to boot
2424 */
2425static void
2426boot_queue (struct Queue *queue)
2427{
2428 queue->nt =
2429 GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
2430 (void) GNUNET_CONTAINER_multipeermap_put (
2431 queue_map,
2432 &queue->target,
2433 queue,
2434 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2435 GNUNET_STATISTICS_set (stats,
2436 "# queues active",
2437 GNUNET_CONTAINER_multipeermap_size (queue_map),
2438 GNUNET_NO);
2439 queue->timeout =
2440 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2441 queue->mq = GNUNET_MQ_queue_for_callbacks (&mq_send,
2442 &mq_destroy,
2443 &mq_cancel,
2444 queue,
2445 NULL,
2446 &mq_error,
2447 queue);
2448}
2449
2450
2451/**
2452 * Generate and transmit our ephemeral key and the signature for
2453 * the initial KX with the other peer. Must be called first, before
2454 * any other bytes are ever written to the output buffer. Note that
2455 * our cipher must already be initialized when calling this function.
2456 * Helper function for #start_initial_kx_out().
2457 *
2458 * @param queue queue to do KX for
2459 * @param epub our public key for the KX
2460 */
2461static void
2462transmit_kx (struct Queue *queue,
2463 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
2464{
2465 struct TcpHandshakeSignature ths;
2466 struct TCPConfirmation tc;
2467
2468 memcpy (queue->cwrite_buf, epub, sizeof(*epub));
2469 queue->cwrite_off = sizeof(*epub);
2470 /* compute 'tc' and append in encrypted format to cwrite_buf */
2471 tc.sender = my_identity;
2472 tc.monotonic_time =
2473 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
2474 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
2475 &tc.challenge,
2476 sizeof(tc.challenge));
2477 ths.purpose.purpose = htonl (
2478 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2479 ths.purpose.size = htonl (sizeof(ths));
2480 ths.sender = my_identity;
2481 ths.receiver = queue->target;
2482 ths.ephemeral = *epub;
2483 ths.monotonic_time = tc.monotonic_time;
2484 ths.challenge = tc.challenge;
2485 GNUNET_CRYPTO_eddsa_sign (my_private_key,
2486 &ths,
2487 &tc.sender_sig);
2488 GNUNET_assert (0 ==
2489 gcry_cipher_encrypt (queue->out_cipher,
2490 &queue->cwrite_buf[queue->cwrite_off],
2491 sizeof(tc),
2492 &tc,
2493 sizeof(tc)));
2494 queue->challenge = tc.challenge;
2495 queue->cwrite_off += sizeof(tc);
2496
2497 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
2498 "transport",
2499 "handshake written\n");
2500}
2501
2502
2503/**
2504 * Initialize our key material for outgoing transmissions and
2505 * inform the other peer about it. Must be called first before
2506 * any data is sent.
2507 *
2508 * @param queue the queue to setup
2509 */
2510static void
2511start_initial_kx_out (struct Queue *queue)
2512{
2513 struct GNUNET_CRYPTO_EcdhePublicKey epub;
2514
2515 GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
2516 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &epub);
2517 setup_out_cipher (queue);
2518 transmit_kx (queue, &epub);
2519}
2520
2521
2522/**
2523 * Callback called when peerstore store operation for handshake monotime is finished.
2524 * @param cls Queue context the store operation was executed.
2525 * @param success Store operation was successful (GNUNET_OK) or not.
2526 */
2527static void
2528handshake_monotime_store_cb (void *cls, int success)
2529{
2530 struct Queue *queue = cls;
2531 if (GNUNET_OK != success)
2532 {
2533 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2534 "Failed to store handshake monotonic time in PEERSTORE!\n");
2535 }
2536 queue->handshake_monotime_sc = NULL;
2537}
2538
2539
2540/**
2541 * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE
2542 * where found.
2543 * @param cls Queue context the store operation was executed.
2544 * @param record The record found or NULL if there is no record left.
2545 * @param emsg Message from peerstore.
2546 */
2547static void
2548handshake_monotime_cb (void *cls,
2549 const struct GNUNET_PEERSTORE_Record *record,
2550 const char *emsg)
2551{
2552 struct Queue *queue = cls;
2553 struct GNUNET_TIME_AbsoluteNBO *mtbe;
2554 struct GNUNET_TIME_Absolute mt;
2555 const struct GNUNET_PeerIdentity *pid;
2556 struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2557
2558 (void) emsg;
2559
2560 handshake_monotonic_time = &queue->handshake_monotonic_time;
2561 pid = &queue->target;
2562 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2563 "tcp handshake with us %s\n",
2564 GNUNET_i2s (&my_identity));
2565 if (NULL == record)
2566 {
2567 queue->handshake_monotime_get = NULL;
2568 return;
2569 }
2570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2571 "tcp handshake from peer %s\n",
2572 GNUNET_i2s (pid));
2573 if (sizeof(*mtbe) != record->value_size)
2574 {
2575 GNUNET_break (0);
2576 return;
2577 }
2578 mtbe = record->value;
2579 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2580 if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
2581 queue->handshake_monotonic_time).abs_value_us)
2582 {
2583 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2584 "Queue from %s dropped, handshake monotime in the past\n",
2585 GNUNET_i2s (&queue->target));
2586 GNUNET_break (0);
2587 queue_finish (queue);
2588 return;
2589 }
2590 queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2591 "transport_tcp_communicator",
2592 pid,
2593 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
2594 handshake_monotonic_time,
2595 sizeof(*
2596 handshake_monotonic_time),
2597 GNUNET_TIME_UNIT_FOREVER_ABS,
2598 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
2599 &
2600 handshake_monotime_store_cb,
2601 queue);
2602}
2603
2604
2605/**
2606 * We have received the first bytes from the other side on a @a queue.
2607 * Decrypt the @a tc contained in @a ibuf and check the signature.
2608 * Note that #setup_in_cipher() must have already been called.
2609 *
2610 * @param queue queue to decrypt initial bytes from other peer for
2611 * @param tc[out] where to store the result
2612 * @param ibuf incoming data, of size
2613 * `INITIAL_KX_SIZE`
2614 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
2615 */
2616static int
2617decrypt_and_check_tc (struct Queue *queue,
2618 struct TCPConfirmation *tc,
2619 char *ibuf)
2620{
2621 struct TcpHandshakeSignature ths;
2622 enum GNUNET_GenericReturnValue ret;
2623
2624 GNUNET_assert (
2625 0 ==
2626 gcry_cipher_decrypt (queue->in_cipher,
2627 tc,
2628 sizeof(*tc),
2629 &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2630 sizeof(*tc)));
2631 ths.purpose.purpose = htonl (
2632 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2633 ths.purpose.size = htonl (sizeof(ths));
2634 ths.sender = tc->sender;
2635 ths.receiver = my_identity;
2636 memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2637 ths.monotonic_time = tc->monotonic_time;
2638 ths.challenge = tc->challenge;
2639 ret = GNUNET_CRYPTO_eddsa_verify (
2640 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE,
2641 &ths,
2642 &tc->sender_sig,
2643 &tc->sender.public_key);
2644 if (GNUNET_YES == ret)
2645 queue->handshake_monotime_get =
2646 GNUNET_PEERSTORE_iterate (peerstore,
2647 "transport_tcp_communicator",
2648 &queue->target,
2649 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
2650 &handshake_monotime_cb,
2651 queue);
2652 return ret;
2653}
2654
2655
2656/**
2657 * Closes socket and frees memory associated with @a pq.
2658 *
2659 * @param pq proto queue to free
2660 */
2661static void
2662free_proto_queue (struct ProtoQueue *pq)
2663{
2664 if (NULL != pq->listen_sock)
2665 {
2666 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pq->listen_sock));
2667 pq->listen_sock = NULL;
2668 }
2669 GNUNET_NETWORK_socket_close (pq->sock);
2670 GNUNET_free (pq->address);
2671 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
2672 GNUNET_free (pq);
2673}
2674
2675
2676/**
2677 * Read from the socket of the proto queue until we have enough data
2678 * to upgrade to full queue.
2679 *
2680 * @param cls a `struct ProtoQueue`
2681 */
2682static void
2683proto_read_kx (void *cls)
2684{
2685 struct ProtoQueue *pq = cls;
2686 ssize_t rcvd;
2687 struct GNUNET_TIME_Relative left;
2688 struct Queue *queue;
2689 struct TCPConfirmation tc;
2690
2691 pq->read_task = NULL;
2692 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
2693 if (0 == left.rel_value_us)
2694 {
2695 free_proto_queue (pq);
2696 return;
2697 }
2698 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
2699 &pq->ibuf[pq->ibuf_off],
2700 sizeof(pq->ibuf) - pq->ibuf_off);
2701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2702 "Received %lu bytes for KX\n", rcvd);
2703 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
2704 "transport",
2705 "Received %lu bytes for KX\n", rcvd);
2706 if (-1 == rcvd)
2707 {
2708 if ((EAGAIN != errno) && (EINTR != errno))
2709 {
2710 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2711 free_proto_queue (pq);
2712 return;
2713 }
2714 /* try again */
2715 pq->read_task =
2716 GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq);
2717 return;
2718 }
2719 pq->ibuf_off += rcvd;
2720 if (pq->ibuf_off > sizeof(pq->ibuf))
2721 {
2722 /* read more */
2723 pq->read_task =
2724 GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq);
2725 return;
2726 }
2727 /* we got all the data, let's find out who we are talking to! */
2728 queue = GNUNET_new (struct Queue);
2729 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
2730 queue);
2731 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
2732 {
2733 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2734 "Invalid TCP KX received from %s\n",
2735 GNUNET_a2s (pq->address, pq->address_len));
2736 gcry_cipher_close (queue->in_cipher);
2737 GNUNET_free (queue);
2738 free_proto_queue (pq);
2739 return;
2740 }
2741 queue->address = pq->address; /* steals reference */
2742 queue->address_len = pq->address_len;
2743 queue->target = tc.sender;
2744 queue->listen_sock = pq->listen_sock;
2745 queue->sock = pq->sock;
2746
2747 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2748 "created queue with target %s\n",
2749 GNUNET_i2s (&queue->target));
2750
2751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2752 "start kx proto\n");
2753
2754 start_initial_kx_out (queue);
2755 queue->cs = GNUNET_TRANSPORT_CS_INBOUND;
2756 boot_queue (queue);
2757 queue->read_task =
2758 GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2759 queue->sock,
2760 &queue_read,
2761 queue);
2762 queue->write_task =
2763 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2764 queue->sock,
2765 &queue_write,
2766 queue);
2767 // TODO To early! Move it somewhere else.
2768 // send_challenge (tc.challenge, queue);
2769 queue->challenge_received = tc.challenge;
2770
2771 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
2772 GNUNET_free (pq);
2773}
2774
2775
2776/**
2777 * We have been notified that our listen socket has something to
2778 * read. Do the read and reschedule this function to be called again
2779 * once more is available.
2780 *
2781 * @param cls ListenTask with listening socket and task
2782 */
2783static void
2784listen_cb (void *cls)
2785{
2786 struct sockaddr_storage in;
2787 socklen_t addrlen;
2788 struct GNUNET_NETWORK_Handle *sock;
2789 struct ProtoQueue *pq;
2790 struct ListenTask *lt;
2791
2792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2793 "listen_cb\n");
2794
2795 lt = cls;
2796
2797 lt->listen_task = NULL;
2798 GNUNET_assert (NULL != lt->listen_sock);
2799 addrlen = sizeof(in);
2800 memset (&in, 0, sizeof(in));
2801 sock = GNUNET_NETWORK_socket_accept (lt->listen_sock,
2802 (struct sockaddr*) &in,
2803 &addrlen);
2804 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
2805 return; /* system limit reached, wait until connection goes down */
2806 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2807 lt->listen_sock,
2808 &listen_cb,
2809 lt);
2810 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
2811 return;
2812 if (NULL == sock)
2813 {
2814 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
2815 return;
2816 }
2817 pq = GNUNET_new (struct ProtoQueue);
2818 pq->address_len = addrlen;
2819 pq->address = GNUNET_memdup (&in, addrlen);
2820 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
2821 pq->sock = sock;
2822 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
2823 pq->sock,
2824 &proto_read_kx,
2825 pq);
2826 GNUNET_CONTAINER_DLL_insert (proto_head, proto_tail, pq);
2827}
2828
2829
2830/**
2831 * Read from the socket of the queue until we have enough data
2832 * to initialize the decryption logic and can switch to regular
2833 * reading.
2834 *
2835 * @param cls a `struct Queue`
2836 */
2837static void
2838queue_read_kx (void *cls)
2839{
2840 struct Queue *queue = cls;
2841 ssize_t rcvd;
2842 struct GNUNET_TIME_Relative left;
2843 struct TCPConfirmation tc;
2844
2845 queue->read_task = NULL;
2846 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2847 if (0 == left.rel_value_us)
2848 {
2849 queue_destroy (queue);
2850 return;
2851 }
2852 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2853 &queue->cread_buf[queue->cread_off],
2854 BUF_SIZE - queue->cread_off);
2855 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2856 "Received %lu bytes for KX\n",
2857 rcvd);
2858 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
2859 "transport",
2860 "Received %lu bytes for KX\n",
2861 rcvd);
2862 if (-1 == rcvd)
2863 {
2864 if ((EAGAIN != errno) && (EINTR != errno))
2865 {
2866 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2867 queue_destroy (queue);
2868 return;
2869 }
2870 queue->read_task =
2871 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
2872 return;
2873 }
2874 queue->cread_off += rcvd;
2875 if (queue->cread_off < INITIAL_KX_SIZE)
2876 {
2877 /* read more */
2878 queue->read_task =
2879 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
2880 return;
2881 }
2882 /* we got all the data, let's find out who we are talking to! */
2883 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *)
2884 queue->cread_buf,
2885 queue);
2886 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
2887 {
2888 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2889 "Invalid TCP KX received from %s\n",
2890 GNUNET_a2s (queue->address, queue->address_len));
2891 queue_destroy (queue);
2892 return;
2893 }
2894 if (0 !=
2895 memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
2896 {
2897 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2898 "Invalid sender in TCP KX received from %s\n",
2899 GNUNET_a2s (queue->address, queue->address_len));
2900 queue_destroy (queue);
2901 return;
2902 }
2903 send_challenge (tc.challenge, queue);
2904 queue->write_task =
2905 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2906 queue->sock,
2907 &queue_write,
2908 queue);
2909
2910 /* update queue timeout */
2911 reschedule_queue_timeout (queue);
2912 /* prepare to continue with regular read task immediately */
2913 memmove (queue->cread_buf,
2914 &queue->cread_buf[INITIAL_KX_SIZE],
2915 queue->cread_off - (INITIAL_KX_SIZE));
2916 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2917 "cread_off is %lu bytes before adjusting\n",
2918 queue->cread_off);
2919 queue->cread_off -= INITIAL_KX_SIZE;
2920 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2921 "cread_off set to %lu bytes\n",
2922 queue->cread_off);
2923 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue);
2924}
2925
2926
2927/**
2928 * Function called by the transport service to initialize a
2929 * message queue given address information about another peer.
2930 * If and when the communication channel is established, the
2931 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
2932 * to notify the service that the channel is now up. It is
2933 * the responsibility of the communicator to manage sane
2934 * retries and timeouts for any @a peer/@a address combination
2935 * provided by the transport service. Timeouts and retries
2936 * do not need to be signalled to the transport service.
2937 *
2938 * @param cls closure
2939 * @param peer identity of the other peer
2940 * @param address where to send the message, human-readable
2941 * communicator-specific format, 0-terminated, UTF-8
2942 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is
2943 * invalid
2944 */
2945static int
2946mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2947{
2948 struct Queue *queue;
2949 const char *path;
2950 struct sockaddr *in;
2951 socklen_t in_len = 0;
2952 struct GNUNET_NETWORK_Handle *sock;
2953
2954 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2955 "Connecting to %s\n", address);
2956 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
2957 "transport",
2958 "Connecting to %s\n", address);
2959 if (0 != strncmp (address,
2960 COMMUNICATOR_ADDRESS_PREFIX "-",
2961 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2962 {
2963 GNUNET_break_op (0);
2964 return GNUNET_SYSERR;
2965 }
2966 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2967 in = tcp_address_to_sockaddr (path, &in_len);
2968
2969 if (NULL == in)
2970 {
2971 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2972 "Failed to setup TCP socket address\n");
2973 return GNUNET_SYSERR;
2974 }
2975
2976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2977 "in %s\n",
2978 GNUNET_a2s (in, in_len));
2979
2980 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP);
2981 if (NULL == sock)
2982 {
2983 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2984 "socket(%d) failed: %s",
2985 in->sa_family,
2986 strerror (errno));
2987 GNUNET_free (in);
2988 return GNUNET_SYSERR;
2989 }
2990 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
2991 (errno != EINPROGRESS))
2992 {
2993 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2994 "connect to `%s' failed: %s",
2995 address,
2996 strerror (errno));
2997 GNUNET_NETWORK_socket_close (sock);
2998 GNUNET_free (in);
2999 return GNUNET_SYSERR;
3000 }
3001
3002 queue = GNUNET_new (struct Queue);
3003 queue->target = *peer;
3004 queue->address = in;
3005 queue->address_len = in_len;
3006 queue->sock = sock;
3007 queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND;
3008 boot_queue (queue);
3009 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3010 "booted queue with target %s\n",
3011 GNUNET_i2s (&queue->target));
3012 // queue->mq_awaits_continue = GNUNET_YES;
3013 queue->read_task =
3014 GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3015 queue->sock,
3016 &queue_read_kx,
3017 queue);
3018
3019
3020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3021 "start kx mq_init\n");
3022
3023 start_initial_kx_out (queue);
3024 queue->write_task =
3025 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3026 queue->sock,
3027 &queue_write,
3028 queue);
3029 return GNUNET_OK;
3030}
3031
3032
3033/**
3034 * Iterator over all ListenTasks to clean up.
3035 *
3036 * @param cls NULL
3037 * @param key unused
3038 * @param value the ListenTask to cancel.
3039 * @return #GNUNET_OK to continue to iterate
3040 */
3041static int
3042get_lt_delete_it (void *cls,
3043 const struct GNUNET_HashCode *key,
3044 void *value)
3045{
3046 struct ListenTask *lt = value;
3047
3048 (void) cls;
3049 (void) key;
3050 if (NULL != lt->listen_task)
3051 {
3052 GNUNET_SCHEDULER_cancel (lt->listen_task);
3053 lt->listen_task = NULL;
3054 }
3055 if (NULL != lt->listen_sock)
3056 {
3057 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lt->listen_sock));
3058 lt->listen_sock = NULL;
3059 }
3060 return GNUNET_OK;
3061}
3062
3063
3064/**
3065 * Iterator over all message queues to clean up.
3066 *
3067 * @param cls NULL
3068 * @param target unused
3069 * @param value the queue to destroy
3070 * @return #GNUNET_OK to continue to iterate
3071 */
3072static int
3073get_queue_delete_it (void *cls,
3074 const struct GNUNET_PeerIdentity *target,
3075 void *value)
3076{
3077 struct Queue *queue = value;
3078
3079 (void) cls;
3080 (void) target;
3081 queue_destroy (queue);
3082 return GNUNET_OK;
3083}
3084
3085
3086/**
3087 * Shutdown the UNIX communicator.
3088 *
3089 * @param cls NULL (always)
3090 */
3091static void
3092do_shutdown (void *cls)
3093{
3094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3095 "Shutdown %s!\n",
3096 shutdown_running ? "running" : "not running");
3097
3098 if (GNUNET_YES == shutdown_running)
3099 return;
3100 else
3101 shutdown_running = GNUNET_YES;
3102
3103 while (NULL != proto_head)
3104 free_proto_queue (proto_head);
3105 if (NULL != nat)
3106 {
3107 GNUNET_NAT_unregister (nat);
3108 nat = NULL;
3109 }
3110 GNUNET_CONTAINER_multihashmap_iterate (lt_map, &get_lt_delete_it, NULL);
3111 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL);
3112 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
3113 if (NULL != ch)
3114 {
3115 GNUNET_TRANSPORT_communicator_address_remove_all (ch);
3116 GNUNET_TRANSPORT_communicator_disconnect (ch);
3117 ch = NULL;
3118 }
3119 if (NULL != stats)
3120 {
3121 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
3122 stats = NULL;
3123 }
3124 if (NULL != my_private_key)
3125 {
3126 GNUNET_free (my_private_key);
3127 my_private_key = NULL;
3128 }
3129 if (NULL != is)
3130 {
3131 GNUNET_NT_scanner_done (is);
3132 is = NULL;
3133 }
3134 if (NULL != peerstore)
3135 {
3136 GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO);
3137 peerstore = NULL;
3138 }
3139 if (NULL != resolve_request_handle)
3140 {
3141 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3142 resolve_request_handle = NULL;
3143 }
3144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3145 "Shutdown done!\n");
3146}
3147
3148
3149/**
3150 * Function called when the transport service has received an
3151 * acknowledgement for this communicator (!) via a different return
3152 * path.
3153 *
3154 * Not applicable for TCP.
3155 *
3156 * @param cls closure
3157 * @param sender which peer sent the notification
3158 * @param msg payload
3159 */
3160static void
3161enc_notify_cb (void *cls,
3162 const struct GNUNET_PeerIdentity *sender,
3163 const struct GNUNET_MessageHeader *msg)
3164{
3165 (void) cls;
3166 (void) sender;
3167 (void) msg;
3168 GNUNET_break_op (0);
3169}
3170
3171
3172/**
3173 * Signature of the callback passed to #GNUNET_NAT_register() for
3174 * a function to call whenever our set of 'valid' addresses changes.
3175 *
3176 * @param cls closure
3177 * @param app_ctx[in,out] location where the app can store stuff
3178 * on add and retrieve it on remove
3179 * @param add_remove #GNUNET_YES to add a new public IP address,
3180 * #GNUNET_NO to remove a previous (now invalid) one
3181 * @param ac address class the address belongs to
3182 * @param addr either the previous or the new public IP address
3183 * @param addrlen actual length of the @a addr
3184 */
3185static void
3186nat_address_cb (void *cls,
3187 void **app_ctx,
3188 int add_remove,
3189 enum GNUNET_NAT_AddressClass ac,
3190 const struct sockaddr *addr,
3191 socklen_t addrlen)
3192{
3193 char *my_addr;
3194 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
3195
3196 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3197 "nat address cb %s %s\n",
3198 add_remove ? "add" : "remove",
3199 GNUNET_a2s (addr, addrlen));
3200
3201 if (GNUNET_YES == add_remove)
3202 {
3203 enum GNUNET_NetworkType nt;
3204
3205 GNUNET_asprintf (&my_addr,
3206 "%s-%s",
3207 COMMUNICATOR_ADDRESS_PREFIX,
3208 GNUNET_a2s (addr, addrlen));
3209 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3210 ai =
3211 GNUNET_TRANSPORT_communicator_address_add (ch,
3212 my_addr,
3213 nt,
3214 GNUNET_TIME_UNIT_FOREVER_REL);
3215 GNUNET_free (my_addr);
3216 *app_ctx = ai;
3217 }
3218 else
3219 {
3220 ai = *app_ctx;
3221 GNUNET_TRANSPORT_communicator_address_remove (ai);
3222 *app_ctx = NULL;
3223 }
3224}
3225
3226
3227/**
3228 * This method adds addresses to the DLL, that are later register at the NAT service.
3229 */
3230static void
3231add_addr (struct sockaddr *in, socklen_t in_len)
3232{
3233
3234 struct Addresses *saddrs;
3235
3236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3237 "add address %s\n",
3238 GNUNET_a2s (in, in_len));
3239
3240 saddrs = GNUNET_new (struct Addresses);
3241 saddrs->addr = in;
3242 saddrs->addr_len = in_len;
3243 GNUNET_CONTAINER_DLL_insert (addrs_head, addrs_tail, saddrs);
3244
3245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3246 "after add address %s\n",
3247 GNUNET_a2s (in, in_len));
3248
3249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3250 "add address %s\n",
3251 GNUNET_a2s (saddrs->addr, saddrs->addr_len));
3252
3253 addrs_lens++;
3254}
3255
3256
3257/**
3258 * This method launch network interactions for each address we like to bind to.
3259 *
3260 * @param addr The address we will listen to.
3261 * @param in_len The length of the address we will listen to.
3262 * @return GNUNET_SYSERR in case of error. GNUNET_OK in case we are successfully listen to the address.
3263 */
3264static int
3265init_socket (struct sockaddr *addr,
3266 socklen_t in_len)
3267{
3268 struct sockaddr_storage in_sto;
3269 socklen_t sto_len;
3270 struct GNUNET_NETWORK_Handle *listen_sock;
3271 struct ListenTask *lt;
3272 int sockfd;
3273 struct GNUNET_HashCode h_sock;
3274
3275 if (NULL == addr)
3276 {
3277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3278 "Address is NULL.\n");
3279 return GNUNET_SYSERR;
3280 }
3281
3282 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3283 "address %s\n",
3284 GNUNET_a2s (addr, in_len));
3285
3286 listen_sock =
3287 GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3288 if (NULL == listen_sock)
3289 {
3290 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
3291 return GNUNET_SYSERR;
3292 }
3293
3294 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3295 {
3296 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
3297 GNUNET_NETWORK_socket_close (listen_sock);
3298 listen_sock = NULL;
3299 return GNUNET_SYSERR;
3300 }
3301
3302 if (GNUNET_OK !=
3303 GNUNET_NETWORK_socket_listen (listen_sock,
3304 5))
3305 {
3306 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3307 "listen");
3308 GNUNET_NETWORK_socket_close (listen_sock);
3309 listen_sock = NULL;
3310 return GNUNET_SYSERR;
3311 }
3312
3313 /* We might have bound to port 0, allowing the OS to figure it out;
3314 thus, get the real IN-address from the socket */
3315 sto_len = sizeof(in_sto);
3316
3317 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3318 (struct sockaddr *) &in_sto,
3319 &sto_len))
3320 {
3321 memcpy (&in_sto, addr, in_len);
3322 sto_len = in_len;
3323 }
3324
3325 // addr = (struct sockaddr *) &in_sto;
3326 in_len = sto_len;
3327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3328 "Bound to `%s'\n",
3329 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3330 stats = GNUNET_STATISTICS_create ("C-TCP", cfg);
3331
3332 if (NULL == is)
3333 is = GNUNET_NT_scanner_init ();
3334
3335 if (NULL == my_private_key)
3336 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
3337 if (NULL == my_private_key)
3338 {
3339 GNUNET_log (
3340 GNUNET_ERROR_TYPE_ERROR,
3341 _ (
3342 "Transport service is lacking key configuration settings. Exiting.\n"));
3343 if (NULL != resolve_request_handle)
3344 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3345 GNUNET_SCHEDULER_shutdown ();
3346 return GNUNET_SYSERR;
3347 }
3348 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key);
3349 /* start listening */
3350
3351 lt = GNUNET_new (struct ListenTask);
3352 lt->listen_sock = listen_sock;
3353
3354 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3355 listen_sock,
3356 &listen_cb,
3357 lt);
3358
3359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3360 "creating hash\n");
3361 sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3362 GNUNET_CRYPTO_hash (&sockfd,
3363 sizeof(int),
3364 &h_sock);
3365
3366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3367 "creating map\n");
3368 if (NULL == lt_map)
3369 lt_map = GNUNET_CONTAINER_multihashmap_create (2, GNUNET_NO);
3370
3371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3372 "creating map entry\n");
3373 GNUNET_assert (GNUNET_OK ==
3374 GNUNET_CONTAINER_multihashmap_put (lt_map,
3375 &h_sock,
3376 lt,
3377 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3378
3379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3380 "map entry created\n");
3381
3382 if (NULL == queue_map)
3383 queue_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
3384
3385 if (NULL == ch)
3386 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
3387 COMMUNICATOR_CONFIG_SECTION,
3388 COMMUNICATOR_ADDRESS_PREFIX,
3389 GNUNET_TRANSPORT_CC_RELIABLE,
3390 &mq_init,
3391 NULL,
3392 &enc_notify_cb,
3393 NULL);
3394
3395 if (NULL == ch)
3396 {
3397 GNUNET_break (0);
3398 if (NULL != resolve_request_handle)
3399 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3400 GNUNET_SCHEDULER_shutdown ();
3401 return GNUNET_SYSERR;
3402 }
3403
3404 add_addr (addr, in_len);
3405 return GNUNET_OK;
3406
3407}
3408
3409
3410/**
3411 * This method reads from the DLL addrs_head to register them at the NAT service.
3412 */
3413static void
3414nat_register ()
3415{
3416 struct sockaddr **saddrs;
3417 socklen_t *saddr_lens;
3418 int i;
3419 size_t len;
3420
3421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3422 "starting nat register!\n");
3423 len = 0;
3424 i = 0;
3425 saddrs = GNUNET_malloc ((addrs_lens) * sizeof(struct sockaddr *));
3426 saddr_lens = GNUNET_malloc ((addrs_lens) * sizeof(socklen_t));
3427 for (struct Addresses *pos = addrs_head; NULL != pos; pos = pos->next)
3428 {
3429 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3430 "registering address %s\n",
3431 GNUNET_a2s (addrs_head->addr, addrs_head->addr_len));
3432
3433 saddr_lens[i] = addrs_head->addr_len;
3434 len += saddr_lens[i];
3435 saddrs[i] = GNUNET_memdup (addrs_head->addr, saddr_lens[i]);
3436 i++;
3437 }
3438
3439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3440 "registering addresses %lu %lu %lu %lu\n",
3441 (addrs_lens) * sizeof(struct sockaddr *),
3442 (addrs_lens) * sizeof(socklen_t),
3443 len,
3444 sizeof(COMMUNICATOR_CONFIG_SECTION));
3445 nat = GNUNET_NAT_register (cfg,
3446 COMMUNICATOR_CONFIG_SECTION,
3447 IPPROTO_TCP,
3448 addrs_lens,
3449 (const struct sockaddr **) saddrs,
3450 saddr_lens,
3451 &nat_address_cb,
3452 NULL /* FIXME: support reversal: #5529 */,
3453 NULL /* closure */);
3454 for (i = addrs_lens - 1; i >= 0; i--)
3455 GNUNET_free (saddrs[i]);
3456 GNUNET_free (saddrs);
3457 GNUNET_free (saddr_lens);
3458
3459 if (NULL == nat)
3460 {
3461 GNUNET_break (0);
3462 if (NULL != resolve_request_handle)
3463 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3464 GNUNET_SCHEDULER_shutdown ();
3465 }
3466}
3467
3468
3469/**
3470 * This method is the callback called by the resolver API, and wraps method init_socket.
3471 *
3472 * @param cls The port we will bind to.
3473 * @param addr The address we will bind to.
3474 * @param in_len The length of the address we will bind to.
3475 */
3476static void
3477init_socket_resolv (void *cls,
3478 const struct sockaddr *addr,
3479 socklen_t in_len)
3480{
3481 struct sockaddr_in *v4;
3482 struct sockaddr_in6 *v6;
3483 struct sockaddr *in;
3484
3485 (void) cls;
3486 if (NULL != addr)
3487 {
3488 if (AF_INET == addr->sa_family)
3489 {
3490 v4 = (struct sockaddr_in *) addr;
3491 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, bind_port);// _global);
3492 }
3493 else if (AF_INET6 == addr->sa_family)
3494 {
3495 v6 = (struct sockaddr_in6 *) addr;
3496 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, bind_port);// _global);
3497 }
3498 else
3499 {
3500 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3501 "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
3502 addr->sa_family,
3503 AF_INET,
3504 AF_INET6);
3505 return;
3506 }
3507 init_socket (in, in_len);
3508 }
3509 else
3510 {
3511 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3512 "Address is NULL. This might be an error or the resolver finished resolving.\n");
3513 if (NULL == addrs_head)
3514 {
3515 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3516 "Resolver finished resolving, but we do not listen to an address!.\n");
3517 return;
3518 }
3519 nat_register ();
3520 }
3521}
3522
3523
3524/**
3525 * Setup communicator and launch network interactions.
3526 *
3527 * @param cls NULL (always)
3528 * @param args remaining command-line arguments
3529 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
3530 * @param c configuration
3531 */
3532static void
3533run (void *cls,
3534 char *const *args,
3535 const char *cfgfile,
3536 const struct GNUNET_CONFIGURATION_Handle *c)
3537{
3538 char *bindto;
3539 struct sockaddr *in;
3540 socklen_t in_len;
3541 struct sockaddr_in v4;
3542 struct sockaddr_in6 v6;
3543 char *start;
3544 unsigned int port;
3545 char dummy[2];
3546 char *rest = NULL;
3547 struct PortOnlyIpv4Ipv6 *po;
3548 socklen_t addr_len_ipv4;
3549 socklen_t addr_len_ipv6;
3550
3551 (void) cls;
3552 cfg = c;
3553 if (GNUNET_OK !=
3554 GNUNET_CONFIGURATION_get_value_string (cfg,
3555 COMMUNICATOR_CONFIG_SECTION,
3556 "BINDTO",
3557 &bindto))
3558 {
3559 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
3560 COMMUNICATOR_CONFIG_SECTION,
3561 "BINDTO");
3562 return;
3563 }
3564 if (GNUNET_OK !=
3565 GNUNET_CONFIGURATION_get_value_number (cfg,
3566 COMMUNICATOR_CONFIG_SECTION,
3567 "MAX_QUEUE_LENGTH",
3568 &max_queue_length))
3569 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
3570 if (GNUNET_OK !=
3571 GNUNET_CONFIGURATION_get_value_time (cfg,
3572 COMMUNICATOR_CONFIG_SECTION,
3573 "REKEY_INTERVAL",
3574 &rekey_interval))
3575 rekey_interval = DEFAULT_REKEY_INTERVAL;
3576
3577 peerstore = GNUNET_PEERSTORE_connect (cfg);
3578 if (NULL == peerstore)
3579 {
3580 GNUNET_free (bindto);
3581 GNUNET_break (0);
3582 GNUNET_SCHEDULER_shutdown ();
3583 return;
3584 }
3585
3586 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
3587
3588 if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
3589 {
3590 po = tcp_address_to_sockaddr_port_only (bindto, &bind_port);
3591 addr_len_ipv4 = po->addr_len_ipv4;
3592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3593 "address po %s\n",
3594 GNUNET_a2s (po->addr_ipv4, addr_len_ipv4));
3595 if (NULL != po->addr_ipv4)
3596 {
3597 init_socket (po->addr_ipv4, addr_len_ipv4);
3598 }
3599 if (NULL != po->addr_ipv6)
3600 {
3601 addr_len_ipv6 = po->addr_len_ipv6;
3602 init_socket (po->addr_ipv6, addr_len_ipv6);
3603 }
3604 GNUNET_free (po);
3605 nat_register ();
3606 GNUNET_free (bindto);
3607 return;
3608 }
3609
3610 start = extract_address (bindto);
3611 // FIXME: check for NULL == start...
3612 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
3613 {
3614 bind_port = extract_port (bindto);
3615
3616 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, v4, bind_port);
3617 init_socket (in, in_len);
3618 nat_register ();
3619 GNUNET_free (start);
3620 GNUNET_free (bindto);
3621 return;
3622 }
3623
3624 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
3625 {
3626 bind_port = extract_port (bindto);
3627 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, v6, bind_port);
3628 init_socket (in, in_len);
3629 nat_register ();
3630 GNUNET_free (start);
3631 GNUNET_free (bindto);
3632 return;
3633 }
3634
3635 bind_port = extract_port (bindto);
3636 resolve_request_handle = GNUNET_RESOLVER_ip_get (strtok_r (bindto,
3637 ":",
3638 &rest),
3639 AF_UNSPEC,
3640 GNUNET_TIME_UNIT_MINUTES,
3641 &init_socket_resolv,
3642 &port);
3643 GNUNET_free (bindto);
3644 GNUNET_free (start);
3645}
3646
3647
3648/**
3649 * The main function for the UNIX communicator.
3650 *
3651 * @param argc number of arguments from the command line
3652 * @param argv command line arguments
3653 * @return 0 ok, 1 on error
3654 */
3655int
3656main (int argc, char *const *argv)
3657{
3658 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3659 GNUNET_GETOPT_OPTION_END
3660 };
3661 int ret;
3662
3663 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
3664 "transport",
3665 "Starting tcp communicator\n");
3666 if (GNUNET_OK !=
3667 GNUNET_STRINGS_get_utf8_args (argc, argv,
3668 &argc, &argv))
3669 return 2;
3670
3671 ret = (GNUNET_OK ==
3672 GNUNET_PROGRAM_run (argc,
3673 argv,
3674 "gnunet-communicator-tcp",
3675 _ ("GNUnet TCP communicator"),
3676 options,
3677 &run,
3678 NULL))
3679 ? 0
3680 : 1;
3681 GNUNET_free_nz ((void *) argv);
3682 return ret;
3683}
3684
3685
3686/* end of gnunet-communicator-tcp.c */