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