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 * - add and use util/ check for IPv6 availability (#5553)
28 * - support DNS names in BINDTO option (#5528)
29 * - support NAT connection reversal method (#5529)
30 * - support other TCP-specific NAT traversal methods (#5531)
31 * - add replay protection support to the protocol by
32 * adding a nonce in the KX and requiring (!) a
33 * nounce ACK to be send within the first X bytes of
37 #include "gnunet_util_lib.h"
38 #include "gnunet_protocols.h"
39 #include "gnunet_signatures.h"
40 #include "gnunet_constants.h"
41 #include "gnunet_nt_lib.h"
42 #include "gnunet_nat_service.h"
43 #include "gnunet_statistics_service.h"
44 #include "gnunet_transport_communication_service.h"
47 * How many messages do we keep at most in the queue to the
48 * transport service before we start to drop (default,
49 * can be changed via the configuration file).
50 * Should be _below_ the level of the communicator API, as
51 * otherwise we may read messages just to have them dropped
52 * by the communicator API.
54 #define DEFAULT_MAX_QUEUE_LENGTH 8
57 * Size of our IO buffers for ciphertext data. Must be at
58 * least UINT_MAX + sizeof (struct TCPBox).
60 #define BUF_SIZE (2 * 64 * 1024 + sizeof (struct TCPBox))
63 * How often do we rekey based on time (at least)
65 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
68 * How long do we wait until we must have received the initial KX?
70 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
73 * How often do we rekey based on number of bytes transmitted?
74 * (additionally randomized).
76 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
79 * Size of the initial key exchange message sent first in both
82 #define INITIAL_KX_SIZE (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof (struct TCPConfirmation))
86 * Address prefix used by the communicator.
88 #define COMMUNICATOR_ADDRESS_PREFIX "tcp"
91 * Configuration section used by the communicator.
93 #define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
95 GNUNET_NETWORK_STRUCT_BEGIN
99 * Signature we use to verify that the ephemeral key was really chosen by
100 * the specified sender.
102 struct TcpHandshakeSignature
105 * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
107 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
110 * Identity of the inititor of the TCP connection (TCP client).
112 struct GNUNET_PeerIdentity sender;
115 * Presumed identity of the target of the TCP connection (TCP server)
117 struct GNUNET_PeerIdentity receiver;
120 * Ephemeral key used by the @e sender.
122 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
125 * Monotonic time of @e sender, to possibly help detect replay attacks
126 * (if receiver persists times by sender).
128 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
133 * Encrypted continuation of TCP initial handshake.
135 struct TCPConfirmation
140 struct GNUNET_PeerIdentity sender;
143 * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
145 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
148 * Monotonic time of @e sender, to possibly help detect replay attacks
149 * (if receiver persists times by sender).
151 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
157 * TCP message box. Always sent encrypted!
163 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX. Warning: the
164 * header size EXCLUDES the size of the `struct TCPBox`. We usually
165 * never do this, but here the payload may truly be 64k *after* the
166 * TCPBox (as we have no MTU)!!
168 struct GNUNET_MessageHeader header;
171 * HMAC for the following encrypted message. Yes, we MUST use
172 * mac-then-encrypt here, as we want to hide the message sizes on
173 * the wire (zero plaintext design!). Using CTR mode padding oracle
174 * attacks do not apply. Besides, due to the use of ephemeral keys
175 * (hopefully with effective replay protection from monotonic time!)
176 * the attacker is limited in using the oracle.
178 struct GNUNET_ShortHashCode hmac;
180 /* followed by as may bytes of payload as indicated in @e header,
181 excluding the TCPBox itself! */
187 * TCP rekey message box. Always sent encrypted! Data after
188 * this message will use the new key.
194 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
196 struct GNUNET_MessageHeader header;
199 * HMAC for the following encrypted message. Yes, we MUST use
200 * mac-then-encrypt here, as we want to hide the message sizes on
201 * the wire (zero plaintext design!). Using CTR mode padding oracle
202 * attacks do not apply. Besides, due to the use of ephemeral keys
203 * (hopefully with effective replay protection from monotonic time!)
204 * the attacker is limited in using the oracle.
206 struct GNUNET_ShortHashCode hmac;
211 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
214 * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY
216 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
219 * Monotonic time of @e sender, to possibly help detect replay attacks
220 * (if receiver persists times by sender).
222 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
228 * TCP finish. Sender asks for the connection to be closed.
229 * Needed/useful in case we drop RST/FIN packets on the GNUnet
230 * port due to the possibility of malicious RST/FIN injection.
236 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
238 struct GNUNET_MessageHeader header;
241 * HMAC for the following encrypted message. Yes, we MUST use
242 * mac-then-encrypt here, as we want to hide the message sizes on
243 * the wire (zero plaintext design!). Using CTR mode padding oracle
244 * attacks do not apply. Besides, due to the use of ephemeral keys
245 * (hopefully with effective replay protection from monotonic time!)
246 * the attacker is limited in using the oracle.
248 struct GNUNET_ShortHashCode hmac;
253 GNUNET_NETWORK_STRUCT_END
257 * Handle for a queue.
263 * To whom are we talking to.
265 struct GNUNET_PeerIdentity target;
268 * socket that we transmit all data with on this queue
270 struct GNUNET_NETWORK_Handle *sock;
273 * cipher for decryption of incoming data.
275 gcry_cipher_hd_t in_cipher;
278 * cipher for encryption of outgoing data.
280 gcry_cipher_hd_t out_cipher;
283 * Shared secret for HMAC verification on incoming data.
285 struct GNUNET_HashCode in_hmac;
288 * Shared secret for HMAC generation on outgoing data, ratcheted after
291 struct GNUNET_HashCode out_hmac;
294 * Our ephemeral key. Stored here temporarily during rekeying / key generation.
296 struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral;
299 * ID of read task for this connection.
301 struct GNUNET_SCHEDULER_Task *read_task;
304 * ID of write task for this connection.
306 struct GNUNET_SCHEDULER_Task *write_task;
309 * Address of the other peer.
311 struct sockaddr *address;
314 * How many more bytes may we sent with the current @e out_cipher
315 * before we should rekey?
317 uint64_t rekey_left_bytes;
320 * Until what time may we sent with the current @e out_cipher
321 * before we should rekey?
323 struct GNUNET_TIME_Absolute rekey_time;
326 * Length of the address.
328 socklen_t address_len;
331 * Message queue we are providing for the #ch.
333 struct GNUNET_MQ_Handle *mq;
336 * handle for this queue with the #ch.
338 struct GNUNET_TRANSPORT_QueueHandle *qh;
341 * Number of bytes we currently have in our write queue.
343 unsigned long long bytes_in_queue;
346 * Buffer for reading ciphertext from network into.
348 char cread_buf[BUF_SIZE];
351 * buffer for writing ciphertext to network.
353 char cwrite_buf[BUF_SIZE];
356 * Plaintext buffer for decrypted plaintext.
358 char pread_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
361 * Plaintext buffer for messages to be encrypted.
363 char pwrite_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
366 * At which offset in the ciphertext read buffer should we
367 * append more ciphertext for transmission next?
372 * At which offset in the ciphertext write buffer should we
373 * append more ciphertext from reading next?
378 * At which offset in the plaintext input buffer should we
379 * append more plaintext from decryption next?
384 * At which offset in the plaintext output buffer should we
385 * append more plaintext for encryption next?
390 * Timeout for this queue.
392 struct GNUNET_TIME_Absolute timeout;
395 * How may messages did we pass from this queue to CORE for which we
396 * have yet to receive an acknoweldgement that CORE is done with
397 * them? If "large" (or even just non-zero), we should throttle
398 * reading to provide flow control. See also #DEFAULT_MAX_QUEUE_LENGTH
399 * and #max_queue_length.
401 unsigned int backpressure;
404 * Which network type does this queue use?
406 enum GNUNET_NetworkType nt;
409 * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call?
411 int mq_awaits_continue;
414 * Did we enqueue a finish message and are closing down the queue?
419 * Did we technically destroy this queue, but kept the allocation
420 * around because of @e backpressure not being zero yet? Used
421 * simply to delay the final #GNUNET_free() operation until
422 * #core_read_finished_cb() has been called.
427 * #GNUNET_YES after #inject_key() placed the rekey message into the
428 * plaintext buffer. Once the plaintext buffer is drained, this
429 * means we must switch to the new key material.
434 * #GNUNET_YES if we just rekeyed and must thus possibly
435 * re-decrypt ciphertext.
442 * Handle for an incoming connection where we do not yet have enough
443 * information to setup a full queue.
451 struct ProtoQueue *next;
456 struct ProtoQueue *prev;
459 * socket that we transmit all data with on this queue
461 struct GNUNET_NETWORK_Handle *sock;
464 * ID of read task for this connection.
466 struct GNUNET_SCHEDULER_Task *read_task;
469 * Address of the other peer.
471 struct sockaddr *address;
474 * Length of the address.
476 socklen_t address_len;
479 * Timeout for this protoqueue.
481 struct GNUNET_TIME_Absolute timeout;
484 * Buffer for reading all the information we need to upgrade from
485 * protoqueue to queue.
487 char ibuf[INITIAL_KX_SIZE];
490 * Current offset for reading into @e ibuf.
499 static struct GNUNET_SCHEDULER_Task *listen_task;
502 * Maximum queue length before we stop reading towards the transport service.
504 static unsigned long long max_queue_length;
507 * For logging statistics.
509 static struct GNUNET_STATISTICS_Handle *stats;
514 static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
517 * Queues (map from peer identity to `struct Queue`)
519 static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
524 static struct GNUNET_NETWORK_Handle *listen_sock;
529 static struct GNUNET_PeerIdentity my_identity;
534 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
539 static const struct GNUNET_CONFIGURATION_Handle *cfg;
542 * Network scanner to determine network types.
544 static struct GNUNET_NT_InterfaceScanner *is;
547 * Connection to NAT service.
549 static struct GNUNET_NAT_Handle *nat;
552 * Protoqueues DLL head.
554 static struct ProtoQueue *proto_head;
557 * Protoqueues DLL tail.
559 static struct ProtoQueue *proto_tail;
563 * We have been notified that our listen socket has something to
564 * read. Do the read and reschedule this function to be called again
565 * once more is available.
570 listen_cb (void *cls);
574 * Functions with this signature are called whenever we need
575 * to close a queue due to a disconnect or failure to
576 * establish a connection.
578 * @param queue queue to close down
581 queue_destroy (struct Queue *queue)
583 struct GNUNET_MQ_Handle *mq;
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
586 "Disconnecting queue for peer `%s'\n",
587 GNUNET_i2s (&queue->target));
588 if (NULL != (mq = queue->mq))
591 GNUNET_MQ_destroy (mq);
593 if (NULL != queue->qh)
595 GNUNET_TRANSPORT_communicator_mq_del (queue->qh);
598 GNUNET_assert (GNUNET_YES ==
599 GNUNET_CONTAINER_multipeermap_remove (queue_map,
602 GNUNET_STATISTICS_set (stats,
604 GNUNET_CONTAINER_multipeermap_size (queue_map),
606 if (NULL != queue->read_task)
608 GNUNET_SCHEDULER_cancel (queue->read_task);
609 queue->read_task = NULL;
611 if (NULL != queue->write_task)
613 GNUNET_SCHEDULER_cancel (queue->write_task);
614 queue->write_task = NULL;
616 GNUNET_NETWORK_socket_close (queue->sock);
617 gcry_cipher_close (queue->in_cipher);
618 gcry_cipher_close (queue->out_cipher);
619 GNUNET_free (queue->address);
620 if (0 != queue->backpressure)
621 queue->destroyed = GNUNET_YES;
624 if (NULL == listen_task)
625 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
633 * Compute @a mac over @a buf, and ratched the @a hmac_secret.
635 * @param[in,out] hmac_secret secret for HMAC calculation
636 * @param buf buffer to MAC
637 * @param buf_size number of bytes in @a buf
638 * @param smac[out] where to write the HMAC
641 calculate_hmac (struct GNUNET_HashCode *hmac_secret,
644 struct GNUNET_ShortHashCode *smac)
646 struct GNUNET_HashCode mac;
648 GNUNET_CRYPTO_hmac_raw (hmac_secret,
649 sizeof (struct GNUNET_HashCode),
653 /* truncate to `struct GNUNET_ShortHashCode` */
656 sizeof (struct GNUNET_ShortHashCode));
657 /* ratchet hmac key */
658 GNUNET_CRYPTO_hash (hmac_secret,
659 sizeof (struct GNUNET_HashCode),
665 * Append a 'finish' message to the outgoing transmission. Once the
666 * finish has been transmitted, destroy the queue.
668 * @param queue queue to shut down nicely
671 queue_finish (struct Queue *queue)
673 struct TCPFinish fin;
678 fin.header.size = htons (sizeof (fin));
679 fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
680 calculate_hmac (&queue->out_hmac,
684 /* if there is any message left in pwrite_buf, we
685 overwrite it (possibly dropping the last message
686 from CORE hard here) */
687 memcpy (queue->pwrite_buf,
690 queue->pwrite_off = sizeof (fin);
691 /* This flag will ensure that #queue_write() no longer
692 notifies CORE about the possibility of sending
693 more data, and that #queue_write() will call
694 #queue_destroy() once the @c fin was fully written. */
695 queue->finishing = GNUNET_YES;
700 * Increment queue timeout due to activity. We do not immediately
701 * notify the monitor here as that might generate excessive
704 * @param queue queue for which the timeout should be rescheduled
707 reschedule_queue_timeout (struct Queue *queue)
710 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
715 * Queue read task. If we hit the timeout, disconnect it
717 * @param cls the `struct Queue *` to disconnect
720 queue_read (void *cls);
724 * Core tells us it is done processing a message that transport
725 * received on a queue with status @a success.
727 * @param cls a `struct Queue *` where the message originally came from
728 * @param success #GNUNET_OK on success
731 core_read_finished_cb (void *cls,
734 struct Queue *queue = cls;
736 if (GNUNET_OK != success)
737 GNUNET_STATISTICS_update (stats,
738 "# messages lost in communicator API towards CORE",
741 queue->backpressure--;
742 /* handle deferred queue destruction */
743 if ( (queue->destroyed) &&
744 (0 == queue->backpressure) )
749 reschedule_queue_timeout (queue);
750 /* possibly unchoke reading, now that CORE made progress */
751 if (NULL == queue->read_task)
753 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (queue->timeout),
761 * We received @a plaintext_len bytes of @a plaintext on @a queue.
762 * Pass it on to CORE. If transmission is actually happening,
763 * increase backpressure counter.
765 * @param queue the queue that received the plaintext
766 * @param plaintext the plaintext that was received
767 * @param plaintext_len number of bytes of plaintext received
770 pass_plaintext_to_core (struct Queue *queue,
771 const void *plaintext,
772 size_t plaintext_len)
774 const struct GNUNET_MessageHeader *hdr = plaintext;
777 if (ntohs (hdr->size) != plaintext_len)
779 /* NOTE: If we ever allow multiple CORE messages in one
780 BOX, this will have to change! */
784 ret = GNUNET_TRANSPORT_communicator_receive (ch,
787 &core_read_finished_cb,
789 if (GNUNET_OK == ret)
790 queue->backpressure++;
791 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
792 if (GNUNET_SYSERR == ret)
793 GNUNET_STATISTICS_update (stats,
794 "# bytes lost due to CORE not running",
801 * Setup @a cipher based on shared secret @a dh and decrypting
804 * @param dh shared secret
805 * @param pid decrypting peer's identity
806 * @param cipher[out] cipher to initialize
807 * @param hmac_key[out] HMAC key to initialize
810 setup_cipher (const struct GNUNET_HashCode *dh,
811 const struct GNUNET_PeerIdentity *pid,
812 gcry_cipher_hd_t *cipher,
813 struct GNUNET_HashCode *hmac_key)
818 gcry_cipher_open (cipher,
819 GCRY_CIPHER_AES256 /* low level: go for speed */,
820 GCRY_CIPHER_MODE_CTR,
822 GNUNET_assert (GNUNET_YES ==
823 GNUNET_CRYPTO_kdf (key,
832 gcry_cipher_setkey (*cipher,
835 GNUNET_assert (GNUNET_YES ==
836 GNUNET_CRYPTO_kdf (ctr,
845 gcry_cipher_setctr (*cipher,
848 GNUNET_assert (GNUNET_YES ==
849 GNUNET_CRYPTO_kdf (hmac_key,
850 sizeof (struct GNUNET_HashCode),
862 * Setup cipher of @a queue for decryption.
864 * @param ephemeral ephemeral key we received from the other peer
865 * @param queue[in,out] queue to initialize decryption cipher for
868 setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
871 struct GNUNET_HashCode dh;
873 GNUNET_CRYPTO_eddsa_ecdh (my_private_key,
884 * Handle @a rekey message on @a queue. The message was already
885 * HMAC'ed, but we should additionally still check the signature.
886 * Then we need to stop the old cipher and start afresh.
888 * @param queue the queue @a rekey was received on
889 * @param rekey the rekey message
892 do_rekey (struct Queue *queue,
893 const struct TCPRekey *rekey)
895 struct TcpHandshakeSignature thp;
897 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
898 thp.purpose.size = htonl (sizeof (thp));
899 thp.sender = queue->target;
900 thp.receiver = my_identity;
901 thp.ephemeral = rekey->ephemeral;
902 thp.monotonic_time = rekey->monotonic_time;
904 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY,
907 &queue->target.public_key))
910 queue_finish (queue);
913 gcry_cipher_close (queue->in_cipher);
914 queue->rekeyed = GNUNET_YES;
915 setup_in_cipher (&rekey->ephemeral,
921 * Test if we have received a full message in plaintext.
924 * @param queue queue to process inbound plaintext for
925 * @return number of bytes of plaintext handled, 0 for none
928 try_handle_plaintext (struct Queue *queue)
930 const struct GNUNET_MessageHeader *hdr
931 = (const struct GNUNET_MessageHeader *) queue->pread_buf;
932 const struct TCPBox *box
933 = (const struct TCPBox *) queue->pread_buf;
934 const struct TCPRekey *rekey
935 = (const struct TCPRekey *) queue->pread_buf;
936 const struct TCPFinish *fin
937 = (const struct TCPFinish *) queue->pread_buf;
938 struct TCPRekey rekeyz;
939 struct TCPFinish finz;
940 struct GNUNET_ShortHashCode tmac;
942 size_t size = 0; /* make compiler happy */
944 if (sizeof (*hdr) > queue->pread_off)
945 return 0; /* not even a header */
946 type = ntohs (hdr->type);
949 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
950 /* Special case: header size excludes box itself! */
951 if (ntohs (hdr->size) + sizeof (struct TCPBox) > queue->pread_off)
953 calculate_hmac (&queue->in_hmac,
957 if (0 != memcmp (&tmac,
962 queue_finish (queue);
965 pass_plaintext_to_core (queue,
966 (const void *) &box[1],
968 size = ntohs (hdr->size) + sizeof (*box);
970 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
971 if (sizeof (*rekey) > queue->pread_off)
973 if (ntohs (hdr->size) != sizeof (*rekey))
976 queue_finish (queue);
980 memset (&rekeyz.hmac,
982 sizeof (rekeyz.hmac));
983 calculate_hmac (&queue->in_hmac,
987 if (0 != memcmp (&tmac,
992 queue_finish (queue);
997 size = ntohs (hdr->size);
999 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
1000 if (sizeof (*fin) > queue->pread_off)
1002 if (ntohs (hdr->size) != sizeof (*fin))
1004 GNUNET_break_op (0);
1005 queue_finish (queue);
1011 sizeof (finz.hmac));
1012 calculate_hmac (&queue->in_hmac,
1016 if (0 != memcmp (&tmac,
1020 GNUNET_break_op (0);
1021 queue_finish (queue);
1024 /* handle FINISH by destroying queue */
1025 queue_destroy (queue);
1028 GNUNET_break_op (0);
1029 queue_finish (queue);
1032 GNUNET_assert (0 != size);
1038 * Queue read task. If we hit the timeout, disconnect it
1040 * @param cls the `struct Queue *` to disconnect
1043 queue_read (void *cls)
1045 struct Queue *queue = cls;
1046 struct GNUNET_TIME_Relative left;
1049 queue->read_task = NULL;
1050 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1051 &queue->cread_buf[queue->cread_off],
1052 BUF_SIZE - queue->cread_off);
1055 if ( (EAGAIN != errno) &&
1058 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1060 queue_finish (queue);
1065 = GNUNET_SCHEDULER_add_read_net (left,
1072 reschedule_queue_timeout (queue);
1073 queue->cread_off += rcvd;
1074 while ( (queue->pread_off < sizeof (queue->pread_buf)) &&
1075 (queue->cread_off > 0) )
1077 size_t max = GNUNET_MIN (sizeof (queue->pread_buf) - queue->pread_off,
1083 gcry_cipher_decrypt (queue->in_cipher,
1084 &queue->pread_buf[queue->pread_off],
1088 queue->pread_off += max;
1090 while ( (GNUNET_NO == queue->rekeyed) &&
1091 (0 != (done = try_handle_plaintext (queue))) )
1093 /* 'done' bytes of plaintext were used, shift buffer */
1094 GNUNET_assert (done <= queue->pread_off);
1095 /* NOTE: this memmove() could possibly sometimes be
1096 avoided if we pass 'total' into try_handle_plaintext()
1097 and use it at an offset into the buffer there! */
1098 memmove (queue->pread_buf,
1099 &queue->pread_buf[done],
1100 queue->pread_off - done);
1101 queue->pread_off -= done;
1104 /* when we encounter a rekey message, the decryption above uses the
1105 wrong key for everything after the rekey; in that case, we have
1106 to re-do the decryption at 'total' instead of at 'max'. If there
1107 is no rekey and the last message is incomplete (max > total),
1108 it is safe to keep the decryption so we shift by 'max' */
1109 if (GNUNET_YES == queue->rekeyed)
1112 queue->rekeyed = GNUNET_NO;
1114 memmove (queue->cread_buf,
1115 &queue->cread_buf[max],
1116 queue->cread_off - max);
1117 queue->cread_off -= max;
1120 if (BUF_SIZE == queue->cread_off)
1121 return; /* buffer full, suspend reading */
1122 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1123 if (0 != left.rel_value_us)
1125 if (max_queue_length < queue->backpressure)
1127 /* continue reading */
1129 = GNUNET_SCHEDULER_add_read_net (left,
1136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1137 "Queue %p was idle for %s, disconnecting\n",
1139 GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1141 queue_finish (queue);
1146 * Convert TCP bind specification to a `struct sockaddr *`
1148 * @param bindto bind specification to convert
1149 * @param[out] sock_len set to the length of the address
1150 * @return converted bindto specification
1152 static struct sockaddr *
1153 tcp_address_to_sockaddr (const char *bindto,
1154 socklen_t *sock_len)
1156 struct sockaddr *in;
1162 if (1 == SSCANF (bindto,
1167 /* interpreting value as just a PORT number */
1168 if (port > UINT16_MAX)
1170 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1171 "BINDTO specification `%s' invalid: value too large for port\n",
1175 /* FIXME: add test to util/ for IPv6 availability,
1176 and depending on the result, go directly for v4-only */
1178 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1179 COMMUNICATOR_CONFIG_SECTION,
1182 struct sockaddr_in *i4;
1184 i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1185 i4->sin_family = AF_INET;
1186 i4->sin_port = htons ((uint16_t) port);
1187 *sock_len = sizeof (struct sockaddr_in);
1188 in = (struct sockaddr *) i4;
1192 struct sockaddr_in6 *i6;
1194 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1195 i6->sin6_family = AF_INET6;
1196 i6->sin6_port = htons ((uint16_t) port);
1197 *sock_len = sizeof (struct sockaddr_in6);
1198 in = (struct sockaddr *) i6;
1202 cp = GNUNET_strdup (bindto);
1203 colon = strrchr (cp, ':');
1206 /* interpet value after colon as port */
1209 if (1 == SSCANF (colon,
1214 /* interpreting value as just a PORT number */
1215 if (port > UINT16_MAX)
1217 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1218 "BINDTO specification `%s' invalid: value too large for port\n",
1226 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1227 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1235 /* interpret missing port as 0, aka pick any free one */
1240 struct sockaddr_in v4;
1242 if (1 == inet_pton (AF_INET,
1246 v4.sin_port = htons ((uint16_t) port);
1247 in = GNUNET_memdup (&v4,
1249 *sock_len = sizeof (v4);
1256 struct sockaddr_in6 v6;
1260 if ( ('[' == *cp) &&
1261 (']' == cp[strlen (cp)-1]) )
1263 start++; /* skip over '[' */
1264 cp[strlen (cp) -1] = '\0'; /* eat ']' */
1266 if (1 == inet_pton (AF_INET6,
1270 v6.sin6_port = htons ((uint16_t) port);
1271 in = GNUNET_memdup (&v6,
1273 *sock_len = sizeof (v6);
1278 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
1285 * Setup cipher for outgoing data stream based on target and
1286 * our ephemeral private key.
1288 * @param queue queue to setup outgoing (encryption) cipher for
1291 setup_out_cipher (struct Queue *queue)
1293 struct GNUNET_HashCode dh;
1295 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral,
1296 &queue->target.public_key,
1298 /* we don't need the private key anymore, drop it! */
1299 memset (&queue->ephemeral,
1301 sizeof (queue->ephemeral));
1307 queue->rekey_time = GNUNET_TIME_relative_to_absolute (REKEY_TIME_INTERVAL);
1308 queue->rekey_left_bytes = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1314 * Inject a `struct TCPRekey` message into the queue's plaintext
1317 * @param queue queue to perform rekeying on
1320 inject_rekey (struct Queue *queue)
1322 struct TCPRekey rekey;
1323 struct TcpHandshakeSignature thp;
1325 GNUNET_assert (0 == queue->pwrite_off);
1329 GNUNET_assert (GNUNET_OK ==
1330 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1331 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1332 rekey.header.size = ntohs (sizeof (rekey));
1333 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1335 rekey.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1336 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
1337 thp.purpose.size = htonl (sizeof (thp));
1338 thp.sender = my_identity;
1339 thp.receiver = queue->target;
1340 thp.ephemeral = rekey.ephemeral;
1341 thp.monotonic_time = rekey.monotonic_time;
1342 GNUNET_assert (GNUNET_OK ==
1343 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1345 &rekey.sender_sig));
1346 calculate_hmac (&queue->out_hmac,
1350 memcpy (queue->pwrite_buf,
1353 queue->rekey_state = GNUNET_YES;
1358 * We encrypted the rekey message, now update actually swap the key
1359 * material and update the key freshness parameters of @a queue.
1362 switch_key (struct Queue *queue)
1364 queue->rekey_state = GNUNET_NO;
1365 gcry_cipher_close (queue->out_cipher);
1366 setup_out_cipher (queue);
1371 * We have been notified that our socket is ready to write.
1372 * Then reschedule this function to be called again once more is available.
1374 * @param cls a `struct Queue`
1377 queue_write (void *cls)
1379 struct Queue *queue = cls;
1382 queue->write_task = NULL;
1383 sent = GNUNET_NETWORK_socket_send (queue->sock,
1386 if ( (-1 == sent) &&
1387 (EAGAIN != errno) &&
1390 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1392 queue_destroy (queue);
1397 size_t usent = (size_t) sent;
1399 memmove (queue->cwrite_buf,
1400 &queue->cwrite_buf[usent],
1401 queue->cwrite_off - usent);
1402 reschedule_queue_timeout (queue);
1404 /* can we encrypt more? (always encrypt full messages, needed
1405 such that #mq_cancel() can work!) */
1406 if (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE)
1409 gcry_cipher_encrypt (queue->out_cipher,
1410 &queue->cwrite_buf[queue->cwrite_off],
1413 queue->pwrite_off));
1414 if (queue->rekey_left_bytes > queue->pwrite_off)
1415 queue->rekey_left_bytes -= queue->pwrite_off;
1417 queue->rekey_left_bytes = 0;
1418 queue->cwrite_off += queue->pwrite_off;
1419 queue->pwrite_off = 0;
1421 if ( (GNUNET_YES == queue->rekey_state) &&
1422 (0 == queue->pwrite_off) )
1424 if ( (0 == queue->pwrite_off) &&
1425 ( (0 == queue->rekey_left_bytes) ||
1426 (0 == GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us) ) )
1427 inject_rekey (queue);
1428 if ( (0 == queue->pwrite_off) &&
1429 (! queue->finishing) &&
1430 (queue->mq_awaits_continue) )
1432 queue->mq_awaits_continue = GNUNET_NO;
1433 GNUNET_MQ_impl_send_continue (queue->mq);
1435 /* did we just finish writing 'finish'? */
1436 if ( (0 == queue->cwrite_off) &&
1437 (GNUNET_YES == queue->finishing) )
1439 queue_destroy (queue);
1442 /* do we care to write more? */
1443 if (0 < queue->cwrite_off)
1445 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1453 * Signature of functions implementing the sending functionality of a
1456 * @param mq the message queue
1457 * @param msg the message to send
1458 * @param impl_state our `struct Queue`
1461 mq_send (struct GNUNET_MQ_Handle *mq,
1462 const struct GNUNET_MessageHeader *msg,
1465 struct Queue *queue = impl_state;
1466 uint16_t msize = ntohs (msg->size);
1469 GNUNET_assert (mq == queue->mq);
1470 if (GNUNET_YES == queue->finishing)
1471 return; /* this queue is dying, drop msg */
1472 GNUNET_assert (0 == queue->pread_off);
1473 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
1474 box.header.size = htons (msize);
1475 calculate_hmac (&queue->out_hmac,
1479 memcpy (&queue->pread_buf[queue->pread_off],
1482 queue->pread_off += sizeof (box);
1483 memcpy (&queue->pread_buf[queue->pread_off],
1486 queue->pread_off += msize;
1487 GNUNET_assert (NULL != queue->sock);
1488 if (NULL == queue->write_task)
1490 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1498 * Signature of functions implementing the destruction of a message
1499 * queue. Implementations must not free @a mq, but should take care
1502 * @param mq the message queue to destroy
1503 * @param impl_state our `struct Queue`
1506 mq_destroy (struct GNUNET_MQ_Handle *mq,
1509 struct Queue *queue = impl_state;
1511 if (mq == queue->mq)
1514 queue_finish (queue);
1520 * Implementation function that cancels the currently sent message.
1522 * @param mq message queue
1523 * @param impl_state our `struct Queue`
1526 mq_cancel (struct GNUNET_MQ_Handle *mq,
1529 struct Queue *queue = impl_state;
1531 GNUNET_assert (0 != queue->pwrite_off);
1532 queue->pwrite_off = 0;
1537 * Generic error handler, called with the appropriate
1538 * error code and the same closure specified at the creation of
1539 * the message queue.
1540 * Not every message queue implementation supports an error handler.
1542 * @param cls our `struct Queue`
1543 * @param error error code
1546 mq_error (void *cls,
1547 enum GNUNET_MQ_Error error)
1549 struct Queue *queue = cls;
1551 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1552 "MQ error in queue to %s: %d\n",
1553 GNUNET_i2s (&queue->target),
1555 queue_finish (queue);
1560 * Add the given @a queue to our internal data structure. Setup the
1561 * MQ processing and inform transport that the queue is ready. Must
1562 * be called after the KX for outgoing messages has been bootstrapped.
1564 * @param queue queue to boot
1567 boot_queue (struct Queue *queue,
1568 enum GNUNET_TRANSPORT_ConnectionStatus cs)
1570 queue->nt = GNUNET_NT_scanner_get_type (is,
1572 queue->address_len);
1573 (void) GNUNET_CONTAINER_multipeermap_put (queue_map,
1576 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1577 GNUNET_STATISTICS_set (stats,
1579 GNUNET_CONTAINER_multipeermap_size (queue_map),
1582 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1584 = GNUNET_MQ_queue_for_callbacks (&mq_send,
1594 switch (queue->address->sa_family)
1597 GNUNET_asprintf (&foreign_addr,
1599 COMMUNICATOR_ADDRESS_PREFIX,
1600 GNUNET_a2s(queue->address,
1601 queue->address_len));
1604 GNUNET_asprintf (&foreign_addr,
1606 COMMUNICATOR_ADDRESS_PREFIX,
1607 GNUNET_a2s(queue->address,
1608 queue->address_len));
1614 = GNUNET_TRANSPORT_communicator_mq_add (ch,
1621 GNUNET_free (foreign_addr);
1627 * Generate and transmit our ephemeral key and the signature for
1628 * the initial KX with the other peer. Must be called first, before
1629 * any other bytes are ever written to the output buffer. Note that
1630 * our cipher must already be initialized when calling this function.
1631 * Helper function for #start_initial_kx_out().
1633 * @param queue queue to do KX for
1634 * @param epub our public key for the KX
1637 transmit_kx (struct Queue *queue,
1638 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1640 struct TcpHandshakeSignature ths;
1641 struct TCPConfirmation tc;
1643 memcpy (queue->cwrite_buf,
1646 queue->cwrite_off = sizeof (epub);
1647 /* compute 'tc' and append in encrypted format to cwrite_buf */
1648 tc.sender = my_identity;
1649 tc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1650 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1651 ths.purpose.size = htonl (sizeof (ths));
1652 ths.sender = my_identity;
1653 ths.receiver = queue->target;
1654 ths.ephemeral = *epub;
1655 ths.monotonic_time = tc.monotonic_time;
1656 GNUNET_assert (GNUNET_OK ==
1657 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1661 gcry_cipher_encrypt (queue->out_cipher,
1662 &queue->cwrite_buf[queue->cwrite_off],
1666 queue->cwrite_off += sizeof (tc);
1671 * Initialize our key material for outgoing transmissions and
1672 * inform the other peer about it. Must be called first before
1675 * @param queue the queue to setup
1678 start_initial_kx_out (struct Queue *queue)
1680 struct GNUNET_CRYPTO_EcdhePublicKey epub;
1682 GNUNET_assert (GNUNET_OK ==
1683 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1684 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1686 setup_out_cipher (queue);
1693 * We have received the first bytes from the other side on a @a queue.
1694 * Decrypt the @a tc contained in @a ibuf and check the signature.
1695 * Note that #setup_in_cipher() must have already been called.
1697 * @param queue queue to decrypt initial bytes from other peer for
1698 * @param tc[out] where to store the result
1699 * @param ibuf incoming data, of size
1701 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
1704 decrypt_and_check_tc (struct Queue *queue,
1705 struct TCPConfirmation *tc,
1708 struct TcpHandshakeSignature ths;
1711 gcry_cipher_decrypt (queue->in_cipher,
1714 &ibuf[sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)],
1716 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1717 ths.purpose.size = htonl (sizeof (ths));
1718 ths.sender = tc->sender;
1719 ths.receiver = my_identity;
1720 memcpy (&ths.ephemeral,
1722 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1723 ths.monotonic_time = tc->monotonic_time;
1724 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
1727 &tc->sender.public_key);
1732 * Closes socket and frees memory associated with @a pq.
1734 * @param pq proto queue to free
1737 free_proto_queue (struct ProtoQueue *pq)
1739 GNUNET_NETWORK_socket_close (pq->sock);
1740 GNUNET_free (pq->address);
1741 GNUNET_CONTAINER_DLL_remove (proto_head,
1749 * Read from the socket of the proto queue until we have enough data
1750 * to upgrade to full queue.
1752 * @param cls a `struct ProtoQueue`
1755 proto_read_kx (void *cls)
1757 struct ProtoQueue *pq = cls;
1759 struct GNUNET_TIME_Relative left;
1760 struct Queue *queue;
1761 struct TCPConfirmation tc;
1763 pq->read_task = NULL;
1764 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
1765 if (0 == left.rel_value_us)
1767 free_proto_queue (pq);
1770 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
1771 &pq->ibuf[pq->ibuf_off],
1772 sizeof (pq->ibuf) - pq->ibuf_off);
1775 if ( (EAGAIN != errno) &&
1778 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1780 free_proto_queue (pq);
1784 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1790 pq->ibuf_off += rcvd;
1791 if (pq->ibuf_off > sizeof (pq->ibuf))
1794 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1800 /* we got all the data, let's find out who we are talking to! */
1801 queue = GNUNET_new (struct Queue);
1802 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
1805 decrypt_and_check_tc (queue,
1809 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1810 "Invalid TCP KX received from %s\n",
1811 GNUNET_a2s (queue->address,
1812 queue->address_len));
1813 gcry_cipher_close (queue->in_cipher);
1814 GNUNET_free (queue);
1815 free_proto_queue (pq);
1818 queue->address = pq->address; /* steals reference */
1819 queue->address_len = pq->address_len;
1820 queue->target = tc.sender;
1821 start_initial_kx_out (queue);
1823 GNUNET_TRANSPORT_CS_INBOUND);
1825 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1829 GNUNET_CONTAINER_DLL_remove (proto_head,
1837 * We have been notified that our listen socket has something to
1838 * read. Do the read and reschedule this function to be called again
1839 * once more is available.
1844 listen_cb (void *cls)
1846 struct sockaddr_storage in;
1848 struct GNUNET_NETWORK_Handle *sock;
1849 struct ProtoQueue *pq;
1852 GNUNET_assert (NULL != listen_sock);
1853 addrlen = sizeof (in);
1857 sock = GNUNET_NETWORK_socket_accept (listen_sock,
1858 (struct sockaddr *) &in,
1860 if ( (NULL == sock) &&
1861 ( (EMFILE == errno) ||
1862 (ENFILE == errno) ) )
1863 return; /* system limit reached, wait until connection goes down */
1864 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1868 if ( (NULL == sock) &&
1869 ( (EAGAIN == errno) ||
1870 (ENOBUFS == errno) ) )
1874 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1878 pq = GNUNET_new (struct ProtoQueue);
1879 pq->address_len = addrlen;
1880 pq->address = GNUNET_memdup (&in,
1882 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
1884 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
1888 GNUNET_CONTAINER_DLL_insert (proto_head,
1895 * Read from the socket of the queue until we have enough data
1896 * to initialize the decryption logic and can switch to regular
1899 * @param cls a `struct Queue`
1902 queue_read_kx (void *cls)
1904 struct Queue *queue = cls;
1906 struct GNUNET_TIME_Relative left;
1907 struct TCPConfirmation tc;
1909 queue->read_task = NULL;
1910 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1911 if (0 == left.rel_value_us)
1913 queue_destroy (queue);
1916 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1917 &queue->cread_buf[queue->cread_off],
1918 BUF_SIZE - queue->cread_off);
1921 if ( (EAGAIN != errno) &&
1924 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1926 queue_destroy (queue);
1929 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1935 queue->cread_off += rcvd;
1936 if (queue->cread_off <
1940 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1946 /* we got all the data, let's find out who we are talking to! */
1947 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) queue->cread_buf,
1950 decrypt_and_check_tc (queue,
1954 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1955 "Invalid TCP KX received from %s\n",
1956 GNUNET_a2s (queue->address,
1957 queue->address_len));
1958 queue_destroy (queue);
1961 if (0 != memcmp (&tc.sender,
1963 sizeof (struct GNUNET_PeerIdentity)))
1965 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1966 "Invalid sender in TCP KX received from %s\n",
1967 GNUNET_a2s (queue->address,
1968 queue->address_len));
1969 queue_destroy (queue);
1973 /* update queue timeout */
1974 reschedule_queue_timeout (queue);
1975 /* prepare to continue with regular read task immediately */
1976 memmove (queue->cread_buf,
1977 &queue->cread_buf[INITIAL_KX_SIZE],
1978 queue->cread_off - (INITIAL_KX_SIZE));
1979 queue->cread_off -= INITIAL_KX_SIZE;
1980 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read,
1986 * Function called by the transport service to initialize a
1987 * message queue given address information about another peer.
1988 * If and when the communication channel is established, the
1989 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
1990 * to notify the service that the channel is now up. It is
1991 * the responsibility of the communicator to manage sane
1992 * retries and timeouts for any @a peer/@a address combination
1993 * provided by the transport service. Timeouts and retries
1994 * do not need to be signalled to the transport service.
1996 * @param cls closure
1997 * @param peer identity of the other peer
1998 * @param address where to send the message, human-readable
1999 * communicator-specific format, 0-terminated, UTF-8
2000 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
2004 const struct GNUNET_PeerIdentity *peer,
2005 const char *address)
2007 struct Queue *queue;
2009 struct sockaddr *in;
2011 struct GNUNET_NETWORK_Handle *sock;
2013 if (0 != strncmp (address,
2014 COMMUNICATOR_ADDRESS_PREFIX "-",
2015 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2017 GNUNET_break_op (0);
2018 return GNUNET_SYSERR;
2020 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2021 in = tcp_address_to_sockaddr (path,
2024 sock = GNUNET_NETWORK_socket_create (in->sa_family,
2029 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2030 "socket(%d) failed: %s",
2034 return GNUNET_SYSERR;
2037 GNUNET_NETWORK_socket_connect (sock,
2041 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2042 "connect to `%s' failed: %s",
2045 GNUNET_NETWORK_socket_close (sock);
2047 return GNUNET_SYSERR;
2050 queue = GNUNET_new (struct Queue);
2051 queue->target = *peer;
2052 queue->address = in;
2053 queue->address_len = in_len;
2056 GNUNET_TRANSPORT_CS_OUTBOUND);
2058 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2064 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2065 "Failed to setup queue to %s at `%s'\n",
2068 GNUNET_NETWORK_socket_close (sock);
2071 start_initial_kx_out (queue);
2077 * Iterator over all message queues to clean up.
2080 * @param target unused
2081 * @param value the queue to destroy
2082 * @return #GNUNET_OK to continue to iterate
2085 get_queue_delete_it (void *cls,
2086 const struct GNUNET_PeerIdentity *target,
2089 struct Queue *queue = value;
2093 queue_destroy (queue);
2099 * Shutdown the UNIX communicator.
2101 * @param cls NULL (always)
2104 do_shutdown (void *cls)
2108 GNUNET_NAT_unregister (nat);
2111 if (NULL != listen_task)
2113 GNUNET_SCHEDULER_cancel (listen_task);
2116 if (NULL != listen_sock)
2118 GNUNET_break (GNUNET_OK ==
2119 GNUNET_NETWORK_socket_close (listen_sock));
2122 GNUNET_CONTAINER_multipeermap_iterate (queue_map,
2123 &get_queue_delete_it,
2125 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
2128 GNUNET_TRANSPORT_communicator_disconnect (ch);
2133 GNUNET_STATISTICS_destroy (stats,
2137 if (NULL != my_private_key)
2139 GNUNET_free (my_private_key);
2140 my_private_key = NULL;
2144 GNUNET_NT_scanner_done (is);
2151 * Function called when the transport service has received an
2152 * acknowledgement for this communicator (!) via a different return
2155 * Not applicable for TCP.
2157 * @param cls closure
2158 * @param sender which peer sent the notification
2159 * @param msg payload
2162 enc_notify_cb (void *cls,
2163 const struct GNUNET_PeerIdentity *sender,
2164 const struct GNUNET_MessageHeader *msg)
2169 GNUNET_break_op (0);
2174 * Signature of the callback passed to #GNUNET_NAT_register() for
2175 * a function to call whenever our set of 'valid' addresses changes.
2177 * @param cls closure
2178 * @param app_ctx[in,out] location where the app can store stuff
2179 * on add and retrieve it on remove
2180 * @param add_remove #GNUNET_YES to add a new public IP address,
2181 * #GNUNET_NO to remove a previous (now invalid) one
2182 * @param ac address class the address belongs to
2183 * @param addr either the previous or the new public IP address
2184 * @param addrlen actual length of the @a addr
2187 nat_address_cb (void *cls,
2190 enum GNUNET_NAT_AddressClass ac,
2191 const struct sockaddr *addr,
2195 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
2197 if (GNUNET_YES == add_remove)
2199 enum GNUNET_NetworkType nt;
2201 GNUNET_asprintf (&my_addr,
2203 COMMUNICATOR_ADDRESS_PREFIX,
2206 nt = GNUNET_NT_scanner_get_type (is,
2209 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2212 GNUNET_TIME_UNIT_FOREVER_REL);
2213 GNUNET_free (my_addr);
2219 GNUNET_TRANSPORT_communicator_address_remove (ai);
2226 * Setup communicator and launch network interactions.
2228 * @param cls NULL (always)
2229 * @param args remaining command-line arguments
2230 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2231 * @param c configuration
2236 const char *cfgfile,
2237 const struct GNUNET_CONFIGURATION_Handle *c)
2240 struct sockaddr *in;
2242 struct sockaddr_storage in_sto;
2248 GNUNET_CONFIGURATION_get_value_filename (cfg,
2249 COMMUNICATOR_CONFIG_SECTION,
2253 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2254 COMMUNICATOR_CONFIG_SECTION,
2259 GNUNET_CONFIGURATION_get_value_number (cfg,
2260 COMMUNICATOR_CONFIG_SECTION,
2263 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2265 in = tcp_address_to_sockaddr (bindto,
2269 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2270 "Failed to setup TCP socket address with path `%s'\n",
2272 GNUNET_free (bindto);
2275 listen_sock = GNUNET_NETWORK_socket_create (in->sa_family,
2278 if (NULL == listen_sock)
2280 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2283 GNUNET_free (bindto);
2287 GNUNET_NETWORK_socket_bind (listen_sock,
2291 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2294 GNUNET_NETWORK_socket_close (listen_sock);
2297 GNUNET_free (bindto);
2300 /* We might have bound to port 0, allowing the OS to figure it out;
2301 thus, get the real IN-address from the socket */
2302 sto_len = sizeof (in_sto);
2303 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
2304 (struct sockaddr *) &in_sto,
2313 GNUNET_free (bindto);
2314 in = (struct sockaddr *) &in_sto;
2316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2318 GNUNET_a2s ((const struct sockaddr *) &in_sto,
2320 stats = GNUNET_STATISTICS_create ("C-TCP",
2322 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
2324 is = GNUNET_NT_scanner_init ();
2325 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2326 if (NULL == my_private_key)
2328 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2329 _("Transport service is lacking key configuration settings. Exiting.\n"));
2330 GNUNET_SCHEDULER_shutdown ();
2333 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
2334 &my_identity.public_key);
2335 /* start listening */
2336 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2340 queue_map = GNUNET_CONTAINER_multipeermap_create (10,
2342 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2343 COMMUNICATOR_CONFIG_SECTION,
2344 COMMUNICATOR_ADDRESS_PREFIX,
2345 GNUNET_TRANSPORT_CC_RELIABLE,
2353 GNUNET_SCHEDULER_shutdown ();
2356 nat = GNUNET_NAT_register (cfg,
2357 COMMUNICATOR_CONFIG_SECTION,
2359 1 /* one address */,
2360 (const struct sockaddr **) &in,
2363 NULL /* FIXME: support reversal: #5529 */,
2364 NULL /* closure */);
2369 * The main function for the UNIX communicator.
2371 * @param argc number of arguments from the command line
2372 * @param argv command line arguments
2373 * @return 0 ok, 1 on error
2379 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2380 GNUNET_GETOPT_OPTION_END
2385 GNUNET_STRINGS_get_utf8_args (argc, argv,
2391 GNUNET_PROGRAM_run (argc, argv,
2392 "gnunet-communicator-tcp",
2393 _("GNUnet TCP communicator"),
2397 GNUNET_free ((void*) argv);
2402 /* end of gnunet-communicator-tcp.c */