2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018, 2019 GNUnet e.V.
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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file transport/gnunet-communicator-tcp.c
23 * @brief Transport plugin using TCP.
24 * @author Christian Grothoff
27 * - support DNS names in BINDTO option (#5528)
28 * - support NAT connection reversal method (#5529)
29 * - support other TCP-specific NAT traversal methods (#5531)
30 * - add replay protection support to the protocol by
31 * adding a nonce in the KX and requiring (!) a
32 * nounce ACK to be send within the first X bytes of
36 #include "gnunet_util_lib.h"
37 #include "gnunet_protocols.h"
38 #include "gnunet_signatures.h"
39 #include "gnunet_constants.h"
40 #include "gnunet_nt_lib.h"
41 #include "gnunet_nat_service.h"
42 #include "gnunet_statistics_service.h"
43 #include "gnunet_transport_communication_service.h"
46 * How many messages do we keep at most in the queue to the
47 * transport service before we start to drop (default,
48 * can be changed via the configuration file).
49 * Should be _below_ the level of the communicator API, as
50 * otherwise we may read messages just to have them dropped
51 * by the communicator API.
53 #define DEFAULT_MAX_QUEUE_LENGTH 8
56 * Size of our IO buffers for ciphertext data. Must be at
57 * least UINT_MAX + sizeof (struct TCPBox).
59 #define BUF_SIZE (2 * 64 * 1024 + sizeof (struct TCPBox))
62 * How often do we rekey based on time (at least)
64 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
67 * How long do we wait until we must have received the initial KX?
69 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
72 * How often do we rekey based on number of bytes transmitted?
73 * (additionally randomized).
75 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
78 * Size of the initial key exchange message sent first in both
81 #define INITIAL_KX_SIZE (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof (struct TCPConfirmation))
85 * Address prefix used by the communicator.
87 #define COMMUNICATOR_ADDRESS_PREFIX "tcp"
90 * Configuration section used by the communicator.
92 #define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
94 GNUNET_NETWORK_STRUCT_BEGIN
98 * Signature we use to verify that the ephemeral key was really chosen by
99 * the specified sender.
101 struct TcpHandshakeSignature
104 * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
106 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
109 * Identity of the inititor of the TCP connection (TCP client).
111 struct GNUNET_PeerIdentity sender;
114 * Presumed identity of the target of the TCP connection (TCP server)
116 struct GNUNET_PeerIdentity receiver;
119 * Ephemeral key used by the @e sender.
121 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
124 * Monotonic time of @e sender, to possibly help detect replay attacks
125 * (if receiver persists times by sender).
127 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
132 * Encrypted continuation of TCP initial handshake.
134 struct TCPConfirmation
139 struct GNUNET_PeerIdentity sender;
142 * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
144 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
147 * Monotonic time of @e sender, to possibly help detect replay attacks
148 * (if receiver persists times by sender).
150 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
156 * TCP message box. Always sent encrypted!
162 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX. Warning: the
163 * header size EXCLUDES the size of the `struct TCPBox`. We usually
164 * never do this, but here the payload may truly be 64k *after* the
165 * TCPBox (as we have no MTU)!!
167 struct GNUNET_MessageHeader header;
170 * HMAC for the following encrypted message. Yes, we MUST use
171 * mac-then-encrypt here, as we want to hide the message sizes on
172 * the wire (zero plaintext design!). Using CTR mode padding oracle
173 * attacks do not apply. Besides, due to the use of ephemeral keys
174 * (hopefully with effective replay protection from monotonic time!)
175 * the attacker is limited in using the oracle.
177 struct GNUNET_ShortHashCode hmac;
179 /* followed by as may bytes of payload as indicated in @e header,
180 excluding the TCPBox itself! */
186 * TCP rekey message box. Always sent encrypted! Data after
187 * this message will use the new key.
193 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
195 struct GNUNET_MessageHeader header;
198 * HMAC for the following encrypted message. Yes, we MUST use
199 * mac-then-encrypt here, as we want to hide the message sizes on
200 * the wire (zero plaintext design!). Using CTR mode padding oracle
201 * attacks do not apply. Besides, due to the use of ephemeral keys
202 * (hopefully with effective replay protection from monotonic time!)
203 * the attacker is limited in using the oracle.
205 struct GNUNET_ShortHashCode hmac;
210 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
213 * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY
215 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
218 * Monotonic time of @e sender, to possibly help detect replay attacks
219 * (if receiver persists times by sender).
221 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
227 * TCP finish. Sender asks for the connection to be closed.
228 * Needed/useful in case we drop RST/FIN packets on the GNUnet
229 * port due to the possibility of malicious RST/FIN injection.
235 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
237 struct GNUNET_MessageHeader header;
240 * HMAC for the following encrypted message. Yes, we MUST use
241 * mac-then-encrypt here, as we want to hide the message sizes on
242 * the wire (zero plaintext design!). Using CTR mode padding oracle
243 * attacks do not apply. Besides, due to the use of ephemeral keys
244 * (hopefully with effective replay protection from monotonic time!)
245 * the attacker is limited in using the oracle.
247 struct GNUNET_ShortHashCode hmac;
252 GNUNET_NETWORK_STRUCT_END
256 * Handle for a queue.
262 * To whom are we talking to.
264 struct GNUNET_PeerIdentity target;
267 * socket that we transmit all data with on this queue
269 struct GNUNET_NETWORK_Handle *sock;
272 * cipher for decryption of incoming data.
274 gcry_cipher_hd_t in_cipher;
277 * cipher for encryption of outgoing data.
279 gcry_cipher_hd_t out_cipher;
282 * Shared secret for HMAC verification on incoming data.
284 struct GNUNET_HashCode in_hmac;
287 * Shared secret for HMAC generation on outgoing data, ratcheted after
290 struct GNUNET_HashCode out_hmac;
293 * Our ephemeral key. Stored here temporarily during rekeying / key generation.
295 struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral;
298 * ID of read task for this connection.
300 struct GNUNET_SCHEDULER_Task *read_task;
303 * ID of write task for this connection.
305 struct GNUNET_SCHEDULER_Task *write_task;
308 * Address of the other peer.
310 struct sockaddr *address;
313 * How many more bytes may we sent with the current @e out_cipher
314 * before we should rekey?
316 uint64_t rekey_left_bytes;
319 * Until what time may we sent with the current @e out_cipher
320 * before we should rekey?
322 struct GNUNET_TIME_Absolute rekey_time;
325 * Length of the address.
327 socklen_t address_len;
330 * Message queue we are providing for the #ch.
332 struct GNUNET_MQ_Handle *mq;
335 * handle for this queue with the #ch.
337 struct GNUNET_TRANSPORT_QueueHandle *qh;
340 * Number of bytes we currently have in our write queue.
342 unsigned long long bytes_in_queue;
345 * Buffer for reading ciphertext from network into.
347 char cread_buf[BUF_SIZE];
350 * buffer for writing ciphertext to network.
352 char cwrite_buf[BUF_SIZE];
355 * Plaintext buffer for decrypted plaintext.
357 char pread_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
360 * Plaintext buffer for messages to be encrypted.
362 char pwrite_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
365 * At which offset in the ciphertext read buffer should we
366 * append more ciphertext for transmission next?
371 * At which offset in the ciphertext write buffer should we
372 * append more ciphertext from reading next?
377 * At which offset in the plaintext input buffer should we
378 * append more plaintext from decryption next?
383 * At which offset in the plaintext output buffer should we
384 * append more plaintext for encryption next?
389 * Timeout for this queue.
391 struct GNUNET_TIME_Absolute timeout;
394 * How may messages did we pass from this queue to CORE for which we
395 * have yet to receive an acknoweldgement that CORE is done with
396 * them? If "large" (or even just non-zero), we should throttle
397 * reading to provide flow control. See also #DEFAULT_MAX_QUEUE_LENGTH
398 * and #max_queue_length.
400 unsigned int backpressure;
403 * Which network type does this queue use?
405 enum GNUNET_NetworkType nt;
408 * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call?
410 int mq_awaits_continue;
413 * Did we enqueue a finish message and are closing down the queue?
418 * Did we technically destroy this queue, but kept the allocation
419 * around because of @e backpressure not being zero yet? Used
420 * simply to delay the final #GNUNET_free() operation until
421 * #core_read_finished_cb() has been called.
426 * #GNUNET_YES after #inject_key() placed the rekey message into the
427 * plaintext buffer. Once the plaintext buffer is drained, this
428 * means we must switch to the new key material.
433 * #GNUNET_YES if we just rekeyed and must thus possibly
434 * re-decrypt ciphertext.
441 * Handle for an incoming connection where we do not yet have enough
442 * information to setup a full queue.
450 struct ProtoQueue *next;
455 struct ProtoQueue *prev;
458 * socket that we transmit all data with on this queue
460 struct GNUNET_NETWORK_Handle *sock;
463 * ID of read task for this connection.
465 struct GNUNET_SCHEDULER_Task *read_task;
468 * Address of the other peer.
470 struct sockaddr *address;
473 * Length of the address.
475 socklen_t address_len;
478 * Timeout for this protoqueue.
480 struct GNUNET_TIME_Absolute timeout;
483 * Buffer for reading all the information we need to upgrade from
484 * protoqueue to queue.
486 char ibuf[INITIAL_KX_SIZE];
489 * Current offset for reading into @e ibuf.
498 static struct GNUNET_SCHEDULER_Task *listen_task;
501 * Maximum queue length before we stop reading towards the transport service.
503 static unsigned long long max_queue_length;
506 * For logging statistics.
508 static struct GNUNET_STATISTICS_Handle *stats;
513 static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
516 * Queues (map from peer identity to `struct Queue`)
518 static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
523 static struct GNUNET_NETWORK_Handle *listen_sock;
528 static struct GNUNET_PeerIdentity my_identity;
533 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
538 static const struct GNUNET_CONFIGURATION_Handle *cfg;
541 * Network scanner to determine network types.
543 static struct GNUNET_NT_InterfaceScanner *is;
546 * Connection to NAT service.
548 static struct GNUNET_NAT_Handle *nat;
551 * Protoqueues DLL head.
553 static struct ProtoQueue *proto_head;
556 * Protoqueues DLL tail.
558 static struct ProtoQueue *proto_tail;
562 * We have been notified that our listen socket has something to
563 * read. Do the read and reschedule this function to be called again
564 * once more is available.
569 listen_cb (void *cls);
573 * Functions with this signature are called whenever we need
574 * to close a queue due to a disconnect or failure to
575 * establish a connection.
577 * @param queue queue to close down
580 queue_destroy (struct Queue *queue)
582 struct GNUNET_MQ_Handle *mq;
584 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
585 "Disconnecting queue for peer `%s'\n",
586 GNUNET_i2s (&queue->target));
587 if (NULL != (mq = queue->mq))
590 GNUNET_MQ_destroy (mq);
592 if (NULL != queue->qh)
594 GNUNET_TRANSPORT_communicator_mq_del (queue->qh);
597 GNUNET_assert (GNUNET_YES ==
598 GNUNET_CONTAINER_multipeermap_remove (queue_map,
601 GNUNET_STATISTICS_set (stats,
603 GNUNET_CONTAINER_multipeermap_size (queue_map),
605 if (NULL != queue->read_task)
607 GNUNET_SCHEDULER_cancel (queue->read_task);
608 queue->read_task = NULL;
610 if (NULL != queue->write_task)
612 GNUNET_SCHEDULER_cancel (queue->write_task);
613 queue->write_task = NULL;
615 GNUNET_NETWORK_socket_close (queue->sock);
616 gcry_cipher_close (queue->in_cipher);
617 gcry_cipher_close (queue->out_cipher);
618 GNUNET_free (queue->address);
619 if (0 != queue->backpressure)
620 queue->destroyed = GNUNET_YES;
623 if (NULL == listen_task)
624 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
632 * Compute @a mac over @a buf, and ratched the @a hmac_secret.
634 * @param[in,out] hmac_secret secret for HMAC calculation
635 * @param buf buffer to MAC
636 * @param buf_size number of bytes in @a buf
637 * @param smac[out] where to write the HMAC
640 calculate_hmac (struct GNUNET_HashCode *hmac_secret,
643 struct GNUNET_ShortHashCode *smac)
645 struct GNUNET_HashCode mac;
647 GNUNET_CRYPTO_hmac_raw (hmac_secret,
648 sizeof (struct GNUNET_HashCode),
652 /* truncate to `struct GNUNET_ShortHashCode` */
655 sizeof (struct GNUNET_ShortHashCode));
656 /* ratchet hmac key */
657 GNUNET_CRYPTO_hash (hmac_secret,
658 sizeof (struct GNUNET_HashCode),
664 * Append a 'finish' message to the outgoing transmission. Once the
665 * finish has been transmitted, destroy the queue.
667 * @param queue queue to shut down nicely
670 queue_finish (struct Queue *queue)
672 struct TCPFinish fin;
677 fin.header.size = htons (sizeof (fin));
678 fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
679 calculate_hmac (&queue->out_hmac,
683 /* if there is any message left in pwrite_buf, we
684 overwrite it (possibly dropping the last message
685 from CORE hard here) */
686 memcpy (queue->pwrite_buf,
689 queue->pwrite_off = sizeof (fin);
690 /* This flag will ensure that #queue_write() no longer
691 notifies CORE about the possibility of sending
692 more data, and that #queue_write() will call
693 #queue_destroy() once the @c fin was fully written. */
694 queue->finishing = GNUNET_YES;
699 * Increment queue timeout due to activity. We do not immediately
700 * notify the monitor here as that might generate excessive
703 * @param queue queue for which the timeout should be rescheduled
706 reschedule_queue_timeout (struct Queue *queue)
709 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
714 * Queue read task. If we hit the timeout, disconnect it
716 * @param cls the `struct Queue *` to disconnect
719 queue_read (void *cls);
723 * Core tells us it is done processing a message that transport
724 * received on a queue with status @a success.
726 * @param cls a `struct Queue *` where the message originally came from
727 * @param success #GNUNET_OK on success
730 core_read_finished_cb (void *cls,
733 struct Queue *queue = cls;
735 if (GNUNET_OK != success)
736 GNUNET_STATISTICS_update (stats,
737 "# messages lost in communicator API towards CORE",
740 queue->backpressure--;
741 /* handle deferred queue destruction */
742 if ( (queue->destroyed) &&
743 (0 == queue->backpressure) )
748 reschedule_queue_timeout (queue);
749 /* possibly unchoke reading, now that CORE made progress */
750 if (NULL == queue->read_task)
752 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (queue->timeout),
760 * We received @a plaintext_len bytes of @a plaintext on @a queue.
761 * Pass it on to CORE. If transmission is actually happening,
762 * increase backpressure counter.
764 * @param queue the queue that received the plaintext
765 * @param plaintext the plaintext that was received
766 * @param plaintext_len number of bytes of plaintext received
769 pass_plaintext_to_core (struct Queue *queue,
770 const void *plaintext,
771 size_t plaintext_len)
773 const struct GNUNET_MessageHeader *hdr = plaintext;
776 if (ntohs (hdr->size) != plaintext_len)
778 /* NOTE: If we ever allow multiple CORE messages in one
779 BOX, this will have to change! */
783 ret = GNUNET_TRANSPORT_communicator_receive (ch,
786 &core_read_finished_cb,
788 if (GNUNET_OK == ret)
789 queue->backpressure++;
790 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
791 if (GNUNET_SYSERR == ret)
792 GNUNET_STATISTICS_update (stats,
793 "# bytes lost due to CORE not running",
800 * Setup @a cipher based on shared secret @a dh and decrypting
803 * @param dh shared secret
804 * @param pid decrypting peer's identity
805 * @param cipher[out] cipher to initialize
806 * @param hmac_key[out] HMAC key to initialize
809 setup_cipher (const struct GNUNET_HashCode *dh,
810 const struct GNUNET_PeerIdentity *pid,
811 gcry_cipher_hd_t *cipher,
812 struct GNUNET_HashCode *hmac_key)
817 gcry_cipher_open (cipher,
818 GCRY_CIPHER_AES256 /* low level: go for speed */,
819 GCRY_CIPHER_MODE_CTR,
821 GNUNET_assert (GNUNET_YES ==
822 GNUNET_CRYPTO_kdf (key,
831 gcry_cipher_setkey (*cipher,
834 GNUNET_assert (GNUNET_YES ==
835 GNUNET_CRYPTO_kdf (ctr,
844 gcry_cipher_setctr (*cipher,
847 GNUNET_assert (GNUNET_YES ==
848 GNUNET_CRYPTO_kdf (hmac_key,
849 sizeof (struct GNUNET_HashCode),
861 * Setup cipher of @a queue for decryption.
863 * @param ephemeral ephemeral key we received from the other peer
864 * @param queue[in,out] queue to initialize decryption cipher for
867 setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
870 struct GNUNET_HashCode dh;
872 GNUNET_CRYPTO_eddsa_ecdh (my_private_key,
883 * Handle @a rekey message on @a queue. The message was already
884 * HMAC'ed, but we should additionally still check the signature.
885 * Then we need to stop the old cipher and start afresh.
887 * @param queue the queue @a rekey was received on
888 * @param rekey the rekey message
891 do_rekey (struct Queue *queue,
892 const struct TCPRekey *rekey)
894 struct TcpHandshakeSignature thp;
896 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
897 thp.purpose.size = htonl (sizeof (thp));
898 thp.sender = queue->target;
899 thp.receiver = my_identity;
900 thp.ephemeral = rekey->ephemeral;
901 thp.monotonic_time = rekey->monotonic_time;
903 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY,
906 &queue->target.public_key))
909 queue_finish (queue);
912 gcry_cipher_close (queue->in_cipher);
913 queue->rekeyed = GNUNET_YES;
914 setup_in_cipher (&rekey->ephemeral,
920 * Test if we have received a full message in plaintext.
923 * @param queue queue to process inbound plaintext for
924 * @return number of bytes of plaintext handled, 0 for none
927 try_handle_plaintext (struct Queue *queue)
929 const struct GNUNET_MessageHeader *hdr
930 = (const struct GNUNET_MessageHeader *) queue->pread_buf;
931 const struct TCPBox *box
932 = (const struct TCPBox *) queue->pread_buf;
933 const struct TCPRekey *rekey
934 = (const struct TCPRekey *) queue->pread_buf;
935 const struct TCPFinish *fin
936 = (const struct TCPFinish *) queue->pread_buf;
937 struct TCPRekey rekeyz;
938 struct TCPFinish finz;
939 struct GNUNET_ShortHashCode tmac;
941 size_t size = 0; /* make compiler happy */
943 if (sizeof (*hdr) > queue->pread_off)
944 return 0; /* not even a header */
945 type = ntohs (hdr->type);
948 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
949 /* Special case: header size excludes box itself! */
950 if (ntohs (hdr->size) + sizeof (struct TCPBox) > queue->pread_off)
952 calculate_hmac (&queue->in_hmac,
956 if (0 != memcmp (&tmac,
961 queue_finish (queue);
964 pass_plaintext_to_core (queue,
965 (const void *) &box[1],
967 size = ntohs (hdr->size) + sizeof (*box);
969 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
970 if (sizeof (*rekey) > queue->pread_off)
972 if (ntohs (hdr->size) != sizeof (*rekey))
975 queue_finish (queue);
979 memset (&rekeyz.hmac,
981 sizeof (rekeyz.hmac));
982 calculate_hmac (&queue->in_hmac,
986 if (0 != memcmp (&tmac,
991 queue_finish (queue);
996 size = ntohs (hdr->size);
998 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
999 if (sizeof (*fin) > queue->pread_off)
1001 if (ntohs (hdr->size) != sizeof (*fin))
1003 GNUNET_break_op (0);
1004 queue_finish (queue);
1010 sizeof (finz.hmac));
1011 calculate_hmac (&queue->in_hmac,
1015 if (0 != memcmp (&tmac,
1019 GNUNET_break_op (0);
1020 queue_finish (queue);
1023 /* handle FINISH by destroying queue */
1024 queue_destroy (queue);
1027 GNUNET_break_op (0);
1028 queue_finish (queue);
1031 GNUNET_assert (0 != size);
1037 * Queue read task. If we hit the timeout, disconnect it
1039 * @param cls the `struct Queue *` to disconnect
1042 queue_read (void *cls)
1044 struct Queue *queue = cls;
1045 struct GNUNET_TIME_Relative left;
1048 queue->read_task = NULL;
1049 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1050 &queue->cread_buf[queue->cread_off],
1051 BUF_SIZE - queue->cread_off);
1054 if ( (EAGAIN != errno) &&
1057 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1059 queue_finish (queue);
1064 = GNUNET_SCHEDULER_add_read_net (left,
1071 reschedule_queue_timeout (queue);
1072 queue->cread_off += rcvd;
1073 while ( (queue->pread_off < sizeof (queue->pread_buf)) &&
1074 (queue->cread_off > 0) )
1076 size_t max = GNUNET_MIN (sizeof (queue->pread_buf) - queue->pread_off,
1082 gcry_cipher_decrypt (queue->in_cipher,
1083 &queue->pread_buf[queue->pread_off],
1087 queue->pread_off += max;
1089 while ( (GNUNET_NO == queue->rekeyed) &&
1090 (0 != (done = try_handle_plaintext (queue))) )
1092 /* 'done' bytes of plaintext were used, shift buffer */
1093 GNUNET_assert (done <= queue->pread_off);
1094 /* NOTE: this memmove() could possibly sometimes be
1095 avoided if we pass 'total' into try_handle_plaintext()
1096 and use it at an offset into the buffer there! */
1097 memmove (queue->pread_buf,
1098 &queue->pread_buf[done],
1099 queue->pread_off - done);
1100 queue->pread_off -= done;
1103 /* when we encounter a rekey message, the decryption above uses the
1104 wrong key for everything after the rekey; in that case, we have
1105 to re-do the decryption at 'total' instead of at 'max'. If there
1106 is no rekey and the last message is incomplete (max > total),
1107 it is safe to keep the decryption so we shift by 'max' */
1108 if (GNUNET_YES == queue->rekeyed)
1111 queue->rekeyed = GNUNET_NO;
1113 memmove (queue->cread_buf,
1114 &queue->cread_buf[max],
1115 queue->cread_off - max);
1116 queue->cread_off -= max;
1119 if (BUF_SIZE == queue->cread_off)
1120 return; /* buffer full, suspend reading */
1121 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1122 if (0 != left.rel_value_us)
1124 if (max_queue_length < queue->backpressure)
1126 /* continue reading */
1128 = GNUNET_SCHEDULER_add_read_net (left,
1135 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1136 "Queue %p was idle for %s, disconnecting\n",
1138 GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1140 queue_finish (queue);
1145 * Convert TCP bind specification to a `struct sockaddr *`
1147 * @param bindto bind specification to convert
1148 * @param[out] sock_len set to the length of the address
1149 * @return converted bindto specification
1151 static struct sockaddr *
1152 tcp_address_to_sockaddr (const char *bindto,
1153 socklen_t *sock_len)
1155 struct sockaddr *in;
1161 if (1 == SSCANF (bindto,
1166 /* interpreting value as just a PORT number */
1167 if (port > UINT16_MAX)
1169 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1170 "BINDTO specification `%s' invalid: value too large for port\n",
1175 GNUNET_NETWORK_test_pf (PF_INET6)) ||
1177 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1178 COMMUNICATOR_CONFIG_SECTION,
1181 struct sockaddr_in *i4;
1183 i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1184 i4->sin_family = AF_INET;
1185 i4->sin_port = htons ((uint16_t) port);
1186 *sock_len = sizeof (struct sockaddr_in);
1187 in = (struct sockaddr *) i4;
1191 struct sockaddr_in6 *i6;
1193 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1194 i6->sin6_family = AF_INET6;
1195 i6->sin6_port = htons ((uint16_t) port);
1196 *sock_len = sizeof (struct sockaddr_in6);
1197 in = (struct sockaddr *) i6;
1201 cp = GNUNET_strdup (bindto);
1202 colon = strrchr (cp, ':');
1205 /* interpet value after colon as port */
1208 if (1 == SSCANF (colon,
1213 /* interpreting value as just a PORT number */
1214 if (port > UINT16_MAX)
1216 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1217 "BINDTO specification `%s' invalid: value too large for port\n",
1225 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1226 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1234 /* interpret missing port as 0, aka pick any free one */
1239 struct sockaddr_in v4;
1241 if (1 == inet_pton (AF_INET,
1245 v4.sin_port = htons ((uint16_t) port);
1246 in = GNUNET_memdup (&v4,
1248 *sock_len = sizeof (v4);
1255 struct sockaddr_in6 v6;
1259 if ( ('[' == *cp) &&
1260 (']' == cp[strlen (cp)-1]) )
1262 start++; /* skip over '[' */
1263 cp[strlen (cp) -1] = '\0'; /* eat ']' */
1265 if (1 == inet_pton (AF_INET6,
1269 v6.sin6_port = htons ((uint16_t) port);
1270 in = GNUNET_memdup (&v6,
1272 *sock_len = sizeof (v6);
1277 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
1284 * Setup cipher for outgoing data stream based on target and
1285 * our ephemeral private key.
1287 * @param queue queue to setup outgoing (encryption) cipher for
1290 setup_out_cipher (struct Queue *queue)
1292 struct GNUNET_HashCode dh;
1294 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral,
1295 &queue->target.public_key,
1297 /* we don't need the private key anymore, drop it! */
1298 memset (&queue->ephemeral,
1300 sizeof (queue->ephemeral));
1306 queue->rekey_time = GNUNET_TIME_relative_to_absolute (REKEY_TIME_INTERVAL);
1307 queue->rekey_left_bytes = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1313 * Inject a `struct TCPRekey` message into the queue's plaintext
1316 * @param queue queue to perform rekeying on
1319 inject_rekey (struct Queue *queue)
1321 struct TCPRekey rekey;
1322 struct TcpHandshakeSignature thp;
1324 GNUNET_assert (0 == queue->pwrite_off);
1328 GNUNET_assert (GNUNET_OK ==
1329 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1330 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1331 rekey.header.size = ntohs (sizeof (rekey));
1332 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1334 rekey.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1335 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
1336 thp.purpose.size = htonl (sizeof (thp));
1337 thp.sender = my_identity;
1338 thp.receiver = queue->target;
1339 thp.ephemeral = rekey.ephemeral;
1340 thp.monotonic_time = rekey.monotonic_time;
1341 GNUNET_assert (GNUNET_OK ==
1342 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1344 &rekey.sender_sig));
1345 calculate_hmac (&queue->out_hmac,
1349 memcpy (queue->pwrite_buf,
1352 queue->rekey_state = GNUNET_YES;
1357 * We encrypted the rekey message, now update actually swap the key
1358 * material and update the key freshness parameters of @a queue.
1361 switch_key (struct Queue *queue)
1363 queue->rekey_state = GNUNET_NO;
1364 gcry_cipher_close (queue->out_cipher);
1365 setup_out_cipher (queue);
1370 * We have been notified that our socket is ready to write.
1371 * Then reschedule this function to be called again once more is available.
1373 * @param cls a `struct Queue`
1376 queue_write (void *cls)
1378 struct Queue *queue = cls;
1381 queue->write_task = NULL;
1382 sent = GNUNET_NETWORK_socket_send (queue->sock,
1385 if ( (-1 == sent) &&
1386 (EAGAIN != errno) &&
1389 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1391 queue_destroy (queue);
1396 size_t usent = (size_t) sent;
1398 memmove (queue->cwrite_buf,
1399 &queue->cwrite_buf[usent],
1400 queue->cwrite_off - usent);
1401 reschedule_queue_timeout (queue);
1403 /* can we encrypt more? (always encrypt full messages, needed
1404 such that #mq_cancel() can work!) */
1405 if (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE)
1408 gcry_cipher_encrypt (queue->out_cipher,
1409 &queue->cwrite_buf[queue->cwrite_off],
1412 queue->pwrite_off));
1413 if (queue->rekey_left_bytes > queue->pwrite_off)
1414 queue->rekey_left_bytes -= queue->pwrite_off;
1416 queue->rekey_left_bytes = 0;
1417 queue->cwrite_off += queue->pwrite_off;
1418 queue->pwrite_off = 0;
1420 if ( (GNUNET_YES == queue->rekey_state) &&
1421 (0 == queue->pwrite_off) )
1423 if ( (0 == queue->pwrite_off) &&
1424 ( (0 == queue->rekey_left_bytes) ||
1425 (0 == GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us) ) )
1426 inject_rekey (queue);
1427 if ( (0 == queue->pwrite_off) &&
1428 (! queue->finishing) &&
1429 (queue->mq_awaits_continue) )
1431 queue->mq_awaits_continue = GNUNET_NO;
1432 GNUNET_MQ_impl_send_continue (queue->mq);
1434 /* did we just finish writing 'finish'? */
1435 if ( (0 == queue->cwrite_off) &&
1436 (GNUNET_YES == queue->finishing) )
1438 queue_destroy (queue);
1441 /* do we care to write more? */
1442 if (0 < queue->cwrite_off)
1444 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1452 * Signature of functions implementing the sending functionality of a
1455 * @param mq the message queue
1456 * @param msg the message to send
1457 * @param impl_state our `struct Queue`
1460 mq_send (struct GNUNET_MQ_Handle *mq,
1461 const struct GNUNET_MessageHeader *msg,
1464 struct Queue *queue = impl_state;
1465 uint16_t msize = ntohs (msg->size);
1468 GNUNET_assert (mq == queue->mq);
1469 if (GNUNET_YES == queue->finishing)
1470 return; /* this queue is dying, drop msg */
1471 GNUNET_assert (0 == queue->pread_off);
1472 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
1473 box.header.size = htons (msize);
1474 calculate_hmac (&queue->out_hmac,
1478 memcpy (&queue->pread_buf[queue->pread_off],
1481 queue->pread_off += sizeof (box);
1482 memcpy (&queue->pread_buf[queue->pread_off],
1485 queue->pread_off += msize;
1486 GNUNET_assert (NULL != queue->sock);
1487 if (NULL == queue->write_task)
1489 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1497 * Signature of functions implementing the destruction of a message
1498 * queue. Implementations must not free @a mq, but should take care
1501 * @param mq the message queue to destroy
1502 * @param impl_state our `struct Queue`
1505 mq_destroy (struct GNUNET_MQ_Handle *mq,
1508 struct Queue *queue = impl_state;
1510 if (mq == queue->mq)
1513 queue_finish (queue);
1519 * Implementation function that cancels the currently sent message.
1521 * @param mq message queue
1522 * @param impl_state our `struct Queue`
1525 mq_cancel (struct GNUNET_MQ_Handle *mq,
1528 struct Queue *queue = impl_state;
1530 GNUNET_assert (0 != queue->pwrite_off);
1531 queue->pwrite_off = 0;
1536 * Generic error handler, called with the appropriate
1537 * error code and the same closure specified at the creation of
1538 * the message queue.
1539 * Not every message queue implementation supports an error handler.
1541 * @param cls our `struct Queue`
1542 * @param error error code
1545 mq_error (void *cls,
1546 enum GNUNET_MQ_Error error)
1548 struct Queue *queue = cls;
1550 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1551 "MQ error in queue to %s: %d\n",
1552 GNUNET_i2s (&queue->target),
1554 queue_finish (queue);
1559 * Add the given @a queue to our internal data structure. Setup the
1560 * MQ processing and inform transport that the queue is ready. Must
1561 * be called after the KX for outgoing messages has been bootstrapped.
1563 * @param queue queue to boot
1566 boot_queue (struct Queue *queue,
1567 enum GNUNET_TRANSPORT_ConnectionStatus cs)
1569 queue->nt = GNUNET_NT_scanner_get_type (is,
1571 queue->address_len);
1572 (void) GNUNET_CONTAINER_multipeermap_put (queue_map,
1575 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1576 GNUNET_STATISTICS_set (stats,
1578 GNUNET_CONTAINER_multipeermap_size (queue_map),
1581 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1583 = GNUNET_MQ_queue_for_callbacks (&mq_send,
1593 switch (queue->address->sa_family)
1596 GNUNET_asprintf (&foreign_addr,
1598 COMMUNICATOR_ADDRESS_PREFIX,
1599 GNUNET_a2s(queue->address,
1600 queue->address_len));
1603 GNUNET_asprintf (&foreign_addr,
1605 COMMUNICATOR_ADDRESS_PREFIX,
1606 GNUNET_a2s(queue->address,
1607 queue->address_len));
1613 = GNUNET_TRANSPORT_communicator_mq_add (ch,
1620 GNUNET_free (foreign_addr);
1626 * Generate and transmit our ephemeral key and the signature for
1627 * the initial KX with the other peer. Must be called first, before
1628 * any other bytes are ever written to the output buffer. Note that
1629 * our cipher must already be initialized when calling this function.
1630 * Helper function for #start_initial_kx_out().
1632 * @param queue queue to do KX for
1633 * @param epub our public key for the KX
1636 transmit_kx (struct Queue *queue,
1637 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1639 struct TcpHandshakeSignature ths;
1640 struct TCPConfirmation tc;
1642 memcpy (queue->cwrite_buf,
1645 queue->cwrite_off = sizeof (epub);
1646 /* compute 'tc' and append in encrypted format to cwrite_buf */
1647 tc.sender = my_identity;
1648 tc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1649 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1650 ths.purpose.size = htonl (sizeof (ths));
1651 ths.sender = my_identity;
1652 ths.receiver = queue->target;
1653 ths.ephemeral = *epub;
1654 ths.monotonic_time = tc.monotonic_time;
1655 GNUNET_assert (GNUNET_OK ==
1656 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1660 gcry_cipher_encrypt (queue->out_cipher,
1661 &queue->cwrite_buf[queue->cwrite_off],
1665 queue->cwrite_off += sizeof (tc);
1670 * Initialize our key material for outgoing transmissions and
1671 * inform the other peer about it. Must be called first before
1674 * @param queue the queue to setup
1677 start_initial_kx_out (struct Queue *queue)
1679 struct GNUNET_CRYPTO_EcdhePublicKey epub;
1681 GNUNET_assert (GNUNET_OK ==
1682 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1683 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1685 setup_out_cipher (queue);
1692 * We have received the first bytes from the other side on a @a queue.
1693 * Decrypt the @a tc contained in @a ibuf and check the signature.
1694 * Note that #setup_in_cipher() must have already been called.
1696 * @param queue queue to decrypt initial bytes from other peer for
1697 * @param tc[out] where to store the result
1698 * @param ibuf incoming data, of size
1700 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
1703 decrypt_and_check_tc (struct Queue *queue,
1704 struct TCPConfirmation *tc,
1707 struct TcpHandshakeSignature ths;
1710 gcry_cipher_decrypt (queue->in_cipher,
1713 &ibuf[sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)],
1715 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1716 ths.purpose.size = htonl (sizeof (ths));
1717 ths.sender = tc->sender;
1718 ths.receiver = my_identity;
1719 memcpy (&ths.ephemeral,
1721 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1722 ths.monotonic_time = tc->monotonic_time;
1723 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
1726 &tc->sender.public_key);
1731 * Closes socket and frees memory associated with @a pq.
1733 * @param pq proto queue to free
1736 free_proto_queue (struct ProtoQueue *pq)
1738 GNUNET_NETWORK_socket_close (pq->sock);
1739 GNUNET_free (pq->address);
1740 GNUNET_CONTAINER_DLL_remove (proto_head,
1748 * Read from the socket of the proto queue until we have enough data
1749 * to upgrade to full queue.
1751 * @param cls a `struct ProtoQueue`
1754 proto_read_kx (void *cls)
1756 struct ProtoQueue *pq = cls;
1758 struct GNUNET_TIME_Relative left;
1759 struct Queue *queue;
1760 struct TCPConfirmation tc;
1762 pq->read_task = NULL;
1763 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
1764 if (0 == left.rel_value_us)
1766 free_proto_queue (pq);
1769 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
1770 &pq->ibuf[pq->ibuf_off],
1771 sizeof (pq->ibuf) - pq->ibuf_off);
1774 if ( (EAGAIN != errno) &&
1777 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1779 free_proto_queue (pq);
1783 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1789 pq->ibuf_off += rcvd;
1790 if (pq->ibuf_off > sizeof (pq->ibuf))
1793 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1799 /* we got all the data, let's find out who we are talking to! */
1800 queue = GNUNET_new (struct Queue);
1801 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
1804 decrypt_and_check_tc (queue,
1808 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1809 "Invalid TCP KX received from %s\n",
1810 GNUNET_a2s (queue->address,
1811 queue->address_len));
1812 gcry_cipher_close (queue->in_cipher);
1813 GNUNET_free (queue);
1814 free_proto_queue (pq);
1817 queue->address = pq->address; /* steals reference */
1818 queue->address_len = pq->address_len;
1819 queue->target = tc.sender;
1820 start_initial_kx_out (queue);
1822 GNUNET_TRANSPORT_CS_INBOUND);
1824 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1828 GNUNET_CONTAINER_DLL_remove (proto_head,
1836 * We have been notified that our listen socket has something to
1837 * read. Do the read and reschedule this function to be called again
1838 * once more is available.
1843 listen_cb (void *cls)
1845 struct sockaddr_storage in;
1847 struct GNUNET_NETWORK_Handle *sock;
1848 struct ProtoQueue *pq;
1851 GNUNET_assert (NULL != listen_sock);
1852 addrlen = sizeof (in);
1856 sock = GNUNET_NETWORK_socket_accept (listen_sock,
1857 (struct sockaddr *) &in,
1859 if ( (NULL == sock) &&
1860 ( (EMFILE == errno) ||
1861 (ENFILE == errno) ) )
1862 return; /* system limit reached, wait until connection goes down */
1863 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1867 if ( (NULL == sock) &&
1868 ( (EAGAIN == errno) ||
1869 (ENOBUFS == errno) ) )
1873 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1877 pq = GNUNET_new (struct ProtoQueue);
1878 pq->address_len = addrlen;
1879 pq->address = GNUNET_memdup (&in,
1881 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
1883 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
1887 GNUNET_CONTAINER_DLL_insert (proto_head,
1894 * Read from the socket of the queue until we have enough data
1895 * to initialize the decryption logic and can switch to regular
1898 * @param cls a `struct Queue`
1901 queue_read_kx (void *cls)
1903 struct Queue *queue = cls;
1905 struct GNUNET_TIME_Relative left;
1906 struct TCPConfirmation tc;
1908 queue->read_task = NULL;
1909 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1910 if (0 == left.rel_value_us)
1912 queue_destroy (queue);
1915 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1916 &queue->cread_buf[queue->cread_off],
1917 BUF_SIZE - queue->cread_off);
1920 if ( (EAGAIN != errno) &&
1923 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1925 queue_destroy (queue);
1928 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1934 queue->cread_off += rcvd;
1935 if (queue->cread_off <
1939 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1945 /* we got all the data, let's find out who we are talking to! */
1946 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) queue->cread_buf,
1949 decrypt_and_check_tc (queue,
1953 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1954 "Invalid TCP KX received from %s\n",
1955 GNUNET_a2s (queue->address,
1956 queue->address_len));
1957 queue_destroy (queue);
1960 if (0 != memcmp (&tc.sender,
1962 sizeof (struct GNUNET_PeerIdentity)))
1964 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1965 "Invalid sender in TCP KX received from %s\n",
1966 GNUNET_a2s (queue->address,
1967 queue->address_len));
1968 queue_destroy (queue);
1972 /* update queue timeout */
1973 reschedule_queue_timeout (queue);
1974 /* prepare to continue with regular read task immediately */
1975 memmove (queue->cread_buf,
1976 &queue->cread_buf[INITIAL_KX_SIZE],
1977 queue->cread_off - (INITIAL_KX_SIZE));
1978 queue->cread_off -= INITIAL_KX_SIZE;
1979 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read,
1985 * Function called by the transport service to initialize a
1986 * message queue given address information about another peer.
1987 * If and when the communication channel is established, the
1988 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
1989 * to notify the service that the channel is now up. It is
1990 * the responsibility of the communicator to manage sane
1991 * retries and timeouts for any @a peer/@a address combination
1992 * provided by the transport service. Timeouts and retries
1993 * do not need to be signalled to the transport service.
1995 * @param cls closure
1996 * @param peer identity of the other peer
1997 * @param address where to send the message, human-readable
1998 * communicator-specific format, 0-terminated, UTF-8
1999 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
2003 const struct GNUNET_PeerIdentity *peer,
2004 const char *address)
2006 struct Queue *queue;
2008 struct sockaddr *in;
2010 struct GNUNET_NETWORK_Handle *sock;
2012 if (0 != strncmp (address,
2013 COMMUNICATOR_ADDRESS_PREFIX "-",
2014 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2016 GNUNET_break_op (0);
2017 return GNUNET_SYSERR;
2019 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2020 in = tcp_address_to_sockaddr (path,
2023 sock = GNUNET_NETWORK_socket_create (in->sa_family,
2028 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2029 "socket(%d) failed: %s",
2033 return GNUNET_SYSERR;
2036 GNUNET_NETWORK_socket_connect (sock,
2040 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2041 "connect to `%s' failed: %s",
2044 GNUNET_NETWORK_socket_close (sock);
2046 return GNUNET_SYSERR;
2049 queue = GNUNET_new (struct Queue);
2050 queue->target = *peer;
2051 queue->address = in;
2052 queue->address_len = in_len;
2055 GNUNET_TRANSPORT_CS_OUTBOUND);
2057 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2063 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2064 "Failed to setup queue to %s at `%s'\n",
2067 GNUNET_NETWORK_socket_close (sock);
2070 start_initial_kx_out (queue);
2076 * Iterator over all message queues to clean up.
2079 * @param target unused
2080 * @param value the queue to destroy
2081 * @return #GNUNET_OK to continue to iterate
2084 get_queue_delete_it (void *cls,
2085 const struct GNUNET_PeerIdentity *target,
2088 struct Queue *queue = value;
2092 queue_destroy (queue);
2098 * Shutdown the UNIX communicator.
2100 * @param cls NULL (always)
2103 do_shutdown (void *cls)
2107 GNUNET_NAT_unregister (nat);
2110 if (NULL != listen_task)
2112 GNUNET_SCHEDULER_cancel (listen_task);
2115 if (NULL != listen_sock)
2117 GNUNET_break (GNUNET_OK ==
2118 GNUNET_NETWORK_socket_close (listen_sock));
2121 GNUNET_CONTAINER_multipeermap_iterate (queue_map,
2122 &get_queue_delete_it,
2124 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
2127 GNUNET_TRANSPORT_communicator_disconnect (ch);
2132 GNUNET_STATISTICS_destroy (stats,
2136 if (NULL != my_private_key)
2138 GNUNET_free (my_private_key);
2139 my_private_key = NULL;
2143 GNUNET_NT_scanner_done (is);
2150 * Function called when the transport service has received an
2151 * acknowledgement for this communicator (!) via a different return
2154 * Not applicable for TCP.
2156 * @param cls closure
2157 * @param sender which peer sent the notification
2158 * @param msg payload
2161 enc_notify_cb (void *cls,
2162 const struct GNUNET_PeerIdentity *sender,
2163 const struct GNUNET_MessageHeader *msg)
2168 GNUNET_break_op (0);
2173 * Signature of the callback passed to #GNUNET_NAT_register() for
2174 * a function to call whenever our set of 'valid' addresses changes.
2176 * @param cls closure
2177 * @param app_ctx[in,out] location where the app can store stuff
2178 * on add and retrieve it on remove
2179 * @param add_remove #GNUNET_YES to add a new public IP address,
2180 * #GNUNET_NO to remove a previous (now invalid) one
2181 * @param ac address class the address belongs to
2182 * @param addr either the previous or the new public IP address
2183 * @param addrlen actual length of the @a addr
2186 nat_address_cb (void *cls,
2189 enum GNUNET_NAT_AddressClass ac,
2190 const struct sockaddr *addr,
2194 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
2196 if (GNUNET_YES == add_remove)
2198 enum GNUNET_NetworkType nt;
2200 GNUNET_asprintf (&my_addr,
2202 COMMUNICATOR_ADDRESS_PREFIX,
2205 nt = GNUNET_NT_scanner_get_type (is,
2208 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2211 GNUNET_TIME_UNIT_FOREVER_REL);
2212 GNUNET_free (my_addr);
2218 GNUNET_TRANSPORT_communicator_address_remove (ai);
2225 * Setup communicator and launch network interactions.
2227 * @param cls NULL (always)
2228 * @param args remaining command-line arguments
2229 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2230 * @param c configuration
2235 const char *cfgfile,
2236 const struct GNUNET_CONFIGURATION_Handle *c)
2239 struct sockaddr *in;
2241 struct sockaddr_storage in_sto;
2247 GNUNET_CONFIGURATION_get_value_filename (cfg,
2248 COMMUNICATOR_CONFIG_SECTION,
2252 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2253 COMMUNICATOR_CONFIG_SECTION,
2258 GNUNET_CONFIGURATION_get_value_number (cfg,
2259 COMMUNICATOR_CONFIG_SECTION,
2262 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2264 in = tcp_address_to_sockaddr (bindto,
2268 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2269 "Failed to setup TCP socket address with path `%s'\n",
2271 GNUNET_free (bindto);
2274 listen_sock = GNUNET_NETWORK_socket_create (in->sa_family,
2277 if (NULL == listen_sock)
2279 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2282 GNUNET_free (bindto);
2286 GNUNET_NETWORK_socket_bind (listen_sock,
2290 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2293 GNUNET_NETWORK_socket_close (listen_sock);
2296 GNUNET_free (bindto);
2299 /* We might have bound to port 0, allowing the OS to figure it out;
2300 thus, get the real IN-address from the socket */
2301 sto_len = sizeof (in_sto);
2302 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
2303 (struct sockaddr *) &in_sto,
2312 GNUNET_free (bindto);
2313 in = (struct sockaddr *) &in_sto;
2315 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2317 GNUNET_a2s ((const struct sockaddr *) &in_sto,
2319 stats = GNUNET_STATISTICS_create ("C-TCP",
2321 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
2323 is = GNUNET_NT_scanner_init ();
2324 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2325 if (NULL == my_private_key)
2327 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2328 _("Transport service is lacking key configuration settings. Exiting.\n"));
2329 GNUNET_SCHEDULER_shutdown ();
2332 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
2333 &my_identity.public_key);
2334 /* start listening */
2335 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2339 queue_map = GNUNET_CONTAINER_multipeermap_create (10,
2341 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2342 COMMUNICATOR_CONFIG_SECTION,
2343 COMMUNICATOR_ADDRESS_PREFIX,
2344 GNUNET_TRANSPORT_CC_RELIABLE,
2352 GNUNET_SCHEDULER_shutdown ();
2355 nat = GNUNET_NAT_register (cfg,
2356 COMMUNICATOR_CONFIG_SECTION,
2358 1 /* one address */,
2359 (const struct sockaddr **) &in,
2362 NULL /* FIXME: support reversal: #5529 */,
2363 NULL /* closure */);
2368 * The main function for the UNIX communicator.
2370 * @param argc number of arguments from the command line
2371 * @param argv command line arguments
2372 * @return 0 ok, 1 on error
2378 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2379 GNUNET_GETOPT_OPTION_END
2384 GNUNET_STRINGS_get_utf8_args (argc, argv,
2390 GNUNET_PROGRAM_run (argc, argv,
2391 "gnunet-communicator-tcp",
2392 _("GNUnet TCP communicator"),
2396 GNUNET_free ((void*) argv);
2401 /* end of gnunet-communicator-tcp.c */