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 (#V6)
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 GNUNET_assert (GNUNET_YES ==
594 GNUNET_CONTAINER_multipeermap_remove (queue_map,
597 GNUNET_STATISTICS_set (stats,
599 GNUNET_CONTAINER_multipeermap_size (queue_map),
601 if (NULL != queue->read_task)
603 GNUNET_SCHEDULER_cancel (queue->read_task);
604 queue->read_task = NULL;
606 if (NULL != queue->write_task)
608 GNUNET_SCHEDULER_cancel (queue->write_task);
609 queue->write_task = NULL;
611 GNUNET_NETWORK_socket_close (queue->sock);
612 gcry_cipher_close (queue->in_cipher);
613 gcry_cipher_close (queue->out_cipher);
614 GNUNET_free (queue->address);
615 if (0 != queue->backpressure)
616 queue->destroyed = GNUNET_YES;
619 if (NULL == listen_task)
620 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
628 * Compute @a mac over @a buf, and ratched the @a hmac_secret.
630 * @param[in,out] hmac_secret secret for HMAC calculation
631 * @param buf buffer to MAC
632 * @param buf_size number of bytes in @a buf
633 * @param smac[out] where to write the HMAC
636 hmac (struct GNUNET_HashCode *hmac_secret,
639 struct GNUNET_ShortHashCode *smac)
641 struct GNUNET_HashCode mac;
643 GNUNET_CRYPTO_hmac_raw (hmac_secret,
644 sizeof (struct GNUNET_HashCode),
648 /* truncate to `struct GNUNET_ShortHashCode` */
651 sizeof (struct GNUNET_ShortHashCode));
652 /* ratchet hmac key */
653 GNUNET_CRYPTO_hash (hmac_secret,
654 sizeof (struct GNUNET_HashCode),
660 * Append a 'finish' message to the outgoing transmission. Once the
661 * finish has been transmitted, destroy the queue.
663 * @param queue queue to shut down nicely
666 queue_finish (struct Queue *queue)
668 struct TCPFinish fin;
673 fin.header.size = htons (sizeof (fin));
674 fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
675 hmac (&queue->out_hmac,
679 /* if there is any message left in pwrite_buf, we
680 overwrite it (possibly dropping the last message
681 from CORE hard here) */
682 memcpy (queue->pwrite_buf,
685 queue->pwrite_off = sizeof (fin);
686 /* This flag will ensure that #queue_write() no longer
687 notifies CORE about the possibility of sending
688 more data, and that #queue_write() will call
689 #queue_destroy() once the @c fin was fully written. */
690 queue->finishing = GNUNET_YES;
695 * Increment queue timeout due to activity. We do not immediately
696 * notify the monitor here as that might generate excessive
699 * @param queue queue for which the timeout should be rescheduled
702 reschedule_queue_timeout (struct Queue *queue)
705 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
710 * Queue read task. If we hit the timeout, disconnect it
712 * @param cls the `struct Queue *` to disconnect
715 queue_read (void *cls);
719 * Core tells us it is done processing a message that transport
720 * received on a queue with status @a success.
722 * @param cls a `struct Queue *` where the message originally came from
723 * @param success #GNUNET_OK on success
726 core_read_finished_cb (void *cls,
729 struct Queue *queue = cls;
731 if (GNUNET_OK != success)
732 GNUNET_STATISTICS_update (stats,
733 "# messages lost in communicator API towards CORE",
736 queue->backpressure--;
737 /* handle deferred queue destruction */
738 if ( (queue->destroyed) &&
739 (0 == queue->backpressure) )
744 reschedule_queue_timeout (queue);
745 /* possibly unchoke reading, now that CORE made progress */
746 if (NULL == queue->read_task)
748 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (queue->timeout),
756 * We received @a plaintext_len bytes of @a plaintext on @a queue.
757 * Pass it on to CORE. If transmission is actually happening,
758 * increase backpressure counter.
760 * @param queue the queue that received the plaintext
761 * @param plaintext the plaintext that was received
762 * @param plaintext_len number of bytes of plaintext received
765 pass_plaintext_to_core (struct Queue *queue,
766 const void *plaintext,
767 size_t plaintext_len)
769 const struct GNUNET_MessageHeader *hdr = plaintext;
772 if (ntohs (hdr->size) != plaintext_len)
774 /* NOTE: If we ever allow multiple CORE messages in one
775 BOX, this will have to change! */
779 ret = GNUNET_TRANSPORT_communicator_receive (ch,
782 &core_read_finished_cb,
784 if (GNUNET_OK == ret)
785 queue->backpressure++;
786 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
787 if (GNUNET_SYSERR == ret)
788 GNUNET_STATISTICS_update (stats,
789 "# bytes lost due to CORE not running",
796 * Setup @a cipher based on shared secret @a dh and decrypting
799 * @param dh shared secret
800 * @param pid decrypting peer's identity
801 * @param cipher[out] cipher to initialize
802 * @param hmac_key[out] HMAC key to initialize
805 setup_cipher (const struct GNUNET_HashCode *dh,
806 const struct GNUNET_PeerIdentity *pid,
807 gcry_cipher_hd_t *cipher,
808 struct GNUNET_HashCode *hmac_key)
813 gcry_cipher_open (cipher,
814 GCRY_CIPHER_AES256 /* low level: go for speed */,
815 GCRY_CIPHER_MODE_CTR,
817 GNUNET_assert (GNUNET_YES ==
818 GNUNET_CRYPTO_kdf (key,
827 gcry_cipher_setkey (*cipher,
830 GNUNET_assert (GNUNET_YES ==
831 GNUNET_CRYPTO_kdf (ctr,
840 gcry_cipher_setctr (*cipher,
843 GNUNET_assert (GNUNET_YES ==
844 GNUNET_CRYPTO_kdf (hmac_key,
845 sizeof (struct GNUNET_HashCode),
857 * Setup cipher of @a queue for decryption.
859 * @param ephemeral ephemeral key we received from the other peer
860 * @param queue[in,out] queue to initialize decryption cipher for
863 setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
866 struct GNUNET_HashCode dh;
868 GNUNET_CRYPTO_eddsa_ecdh (my_private_key,
879 * Handle @a rekey message on @a queue. The message was already
880 * HMAC'ed, but we should additionally still check the signature.
881 * Then we need to stop the old cipher and start afresh.
883 * @param queue the queue @a rekey was received on
884 * @param rekey the rekey message
887 do_rekey (struct Queue *queue,
888 const struct TCPRekey *rekey)
890 struct TcpHandshakeSignature thp;
892 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
893 thp.purpose.size = htonl (sizeof (thp));
894 thp.sender = queue->target;
895 thp.receiver = my_identity;
896 thp.ephemeral = rekey->ephemeral;
897 thp.monotonic_time = rekey->monotonic_time;
899 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY,
902 &queue->target.public_key))
905 queue_finish (queue);
908 gcry_cipher_close (queue->in_cipher);
909 queue->rekeyed = GNUNET_YES;
910 setup_in_cipher (&rekey->ephemeral,
916 * Test if we have received a full message in plaintext.
919 * @param queue queue to process inbound plaintext for
920 * @return number of bytes of plaintext handled, 0 for none
923 try_handle_plaintext (struct Queue *queue)
925 const struct GNUNET_MessageHeader *hdr
926 = (const struct GNUNET_MessageHeader *) queue->pread_buf;
927 const struct TCPBox *box
928 = (const struct TCPBox *) queue->pread_buf;
929 const struct TCPRekey *rekey
930 = (const struct TCPRekey *) queue->pread_buf;
931 const struct TCPFinish *fin
932 = (const struct TCPFinish *) queue->pread_buf;
933 struct TCPRekey rekeyz;
934 struct TCPFinish finz;
935 struct GNUNET_ShortHashCode tmac;
937 size_t size = 0; /* make compiler happy */
939 if (sizeof (*hdr) > queue->pread_off)
940 return 0; /* not even a header */
941 type = ntohs (hdr->type);
944 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
945 /* Special case: header size excludes box itself! */
946 if (ntohs (hdr->size) + sizeof (struct TCPBox) > queue->pread_off)
948 hmac (&queue->in_hmac,
952 if (0 != memcmp (&tmac,
957 queue_finish (queue);
960 pass_plaintext_to_core (queue,
961 (const void *) &box[1],
963 size = ntohs (hdr->size) + sizeof (*box);
965 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
966 if (sizeof (*rekey) > queue->pread_off)
968 if (ntohs (hdr->size) != sizeof (*rekey))
971 queue_finish (queue);
975 memset (&rekeyz.hmac,
977 sizeof (rekeyz.hmac));
978 hmac (&queue->in_hmac,
982 if (0 != memcmp (&tmac,
987 queue_finish (queue);
992 size = ntohs (hdr->size);
994 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
995 if (sizeof (*fin) > queue->pread_off)
997 if (ntohs (hdr->size) != sizeof (*fin))
1000 queue_finish (queue);
1006 sizeof (finz.hmac));
1007 hmac (&queue->in_hmac,
1011 if (0 != memcmp (&tmac,
1015 GNUNET_break_op (0);
1016 queue_finish (queue);
1019 /* handle FINISH by destroying queue */
1020 queue_destroy (queue);
1023 GNUNET_break_op (0);
1024 queue_finish (queue);
1027 GNUNET_assert (0 != size);
1033 * Queue read task. If we hit the timeout, disconnect it
1035 * @param cls the `struct Queue *` to disconnect
1038 queue_read (void *cls)
1040 struct Queue *queue = cls;
1041 struct GNUNET_TIME_Relative left;
1044 queue->read_task = NULL;
1045 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1046 &queue->cread_buf[queue->cread_off],
1047 BUF_SIZE - queue->cread_off);
1050 if ( (EAGAIN != errno) &&
1053 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1055 queue_finish (queue);
1060 = GNUNET_SCHEDULER_add_read_net (left,
1067 reschedule_queue_timeout (queue);
1068 queue->cread_off += rcvd;
1069 while ( (queue->pread_off < sizeof (queue->pread_buf)) &&
1070 (queue->cread_off > 0) )
1072 size_t max = GNUNET_MIN (sizeof (queue->pread_buf) - queue->pread_off,
1078 gcry_cipher_decrypt (queue->in_cipher,
1079 &queue->pread_buf[queue->pread_off],
1083 queue->pread_off += max;
1085 while ( (GNUNET_NO == queue->rekeyed) &&
1086 (0 != (done = try_handle_plaintext (queue))) )
1088 /* 'done' bytes of plaintext were used, shift buffer */
1089 GNUNET_assert (done <= queue->pread_off);
1090 /* NOTE: this memmove() could possibly sometimes be
1091 avoided if we pass 'total' into try_handle_plaintext()
1092 and use it at an offset into the buffer there! */
1093 memmove (queue->pread_buf,
1094 &queue->pread_buf[done],
1095 queue->pread_off - done);
1096 queue->pread_off -= done;
1099 /* when we encounter a rekey message, the decryption above uses the
1100 wrong key for everything after the rekey; in that case, we have
1101 to re-do the decryption at 'total' instead of at 'max'. If there
1102 is no rekey and the last message is incomplete (max > total),
1103 it is safe to keep the decryption so we shift by 'max' */
1104 if (GNUNET_YES == queue->rekeyed)
1107 queue->rekeyed = GNUNET_NO;
1109 memmove (queue->cread_buf,
1110 &queue->cread_buf[max],
1111 queue->cread_off - max);
1112 queue->cread_off -= max;
1115 if (BUF_SIZE == queue->cread_off)
1116 return; /* buffer full, suspend reading */
1117 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1118 if (0 != left.rel_value_us)
1120 if (max_queue_length < queue->backpressure)
1122 /* continue reading */
1124 = GNUNET_SCHEDULER_add_read_net (left,
1131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1132 "Queue %p was idle for %s, disconnecting\n",
1134 GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1136 queue_finish (queue);
1141 * Convert TCP bind specification to a `struct sockaddr *`
1143 * @param bindto bind specification to convert
1144 * @param[out] sock_len set to the length of the address
1145 * @return converted bindto specification
1147 static struct sockaddr *
1148 tcp_address_to_sockaddr (const char *bindto,
1149 socklen_t *sock_len)
1151 struct sockaddr *in;
1157 if (1 == SSCANF (bindto,
1162 /* interpreting value as just a PORT number */
1163 if (port > UINT16_MAX)
1165 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1166 "BINDTO specification `%s' invalid: value too large for port\n",
1170 /* FIXME: add test to util/ for IPv6 availability,
1171 and depending on the result, go directly for v4-only */
1173 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1174 COMMUNICATOR_CONFIG_SECTION,
1177 struct sockaddr_in *i4;
1179 i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1180 i4->sin_family = AF_INET;
1181 i4->sin_port = htons ((uint16_t) port);
1182 *sock_len = sizeof (struct sockaddr_in);
1183 in = (struct sockaddr *) i4;
1187 struct sockaddr_in6 *i6;
1189 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1190 i6->sin6_family = AF_INET6;
1191 i6->sin6_port = htons ((uint16_t) port);
1192 *sock_len = sizeof (struct sockaddr_in6);
1193 in = (struct sockaddr *) i6;
1197 cp = GNUNET_strdup (bindto);
1198 colon = strrchr (cp, ':');
1201 /* interpet value after colon as port */
1204 if (1 == SSCANF (colon,
1209 /* interpreting value as just a PORT number */
1210 if (port > UINT16_MAX)
1212 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1213 "BINDTO specification `%s' invalid: value too large for port\n",
1221 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1222 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1230 /* interpret missing port as 0, aka pick any free one */
1235 struct sockaddr_in v4;
1237 if (1 == inet_pton (AF_INET,
1241 v4.sin_port = htons ((uint16_t) port);
1242 in = GNUNET_memdup (&v4,
1244 *sock_len = sizeof (v4);
1251 struct sockaddr_in6 v6;
1255 if ( ('[' == *cp) &&
1256 (']' == cp[strlen (cp)-1]) )
1258 start++; /* skip over '[' */
1259 cp[strlen (cp) -1] = '\0'; /* eat ']' */
1261 if (1 == inet_pton (AF_INET6,
1265 v6.sin6_port = htons ((uint16_t) port);
1266 in = GNUNET_memdup (&v6,
1268 *sock_len = sizeof (v6);
1273 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
1280 * Setup cipher for outgoing data stream based on target and
1281 * our ephemeral private key.
1283 * @param queue queue to setup outgoing (encryption) cipher for
1286 setup_out_cipher (struct Queue *queue)
1288 struct GNUNET_HashCode dh;
1290 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral,
1291 &queue->target.public_key,
1293 /* we don't need the private key anymore, drop it! */
1294 memset (&queue->ephemeral,
1296 sizeof (queue->ephemeral));
1302 queue->rekey_time = GNUNET_TIME_relative_to_absolute (REKEY_TIME_INTERVAL);
1303 queue->rekey_left_bytes = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1309 * Inject a `struct TCPRekey` message into the queue's plaintext
1312 * @param queue queue to perform rekeying on
1315 inject_rekey (struct Queue *queue)
1317 struct TCPRekey rekey;
1318 struct TcpHandshakeSignature thp;
1320 GNUNET_assert (0 == queue->pwrite_off);
1324 GNUNET_assert (GNUNET_OK ==
1325 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1326 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1327 rekey.header.size = ntohs (sizeof (rekey));
1328 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1330 rekey.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1331 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
1332 thp.purpose.size = htonl (sizeof (thp));
1333 thp.sender = my_identity;
1334 thp.receiver = queue->target;
1335 thp.ephemeral = rekey.ephemeral;
1336 thp.monotonic_time = rekey.monotonic_time;
1337 GNUNET_assert (GNUNET_OK ==
1338 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1340 &rekey.sender_sig));
1341 hmac (&queue->out_hmac,
1345 memcpy (queue->pwrite_buf,
1348 queue->rekey_state = GNUNET_YES;
1353 * We encrypted the rekey message, now update actually swap the key
1354 * material and update the key freshness parameters of @a queue.
1357 switch_key (struct Queue *queue)
1359 queue->rekey_state = GNUNET_NO;
1360 gcry_cipher_close (queue->out_cipher);
1361 setup_out_cipher (queue);
1366 * We have been notified that our socket is ready to write.
1367 * Then reschedule this function to be called again once more is available.
1369 * @param cls a `struct Queue`
1372 queue_write (void *cls)
1374 struct Queue *queue = cls;
1377 queue->write_task = NULL;
1378 sent = GNUNET_NETWORK_socket_send (queue->sock,
1381 if ( (-1 == sent) &&
1382 (EAGAIN != errno) &&
1385 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1387 queue_destroy (queue);
1392 size_t usent = (size_t) sent;
1394 memmove (queue->cwrite_buf,
1395 &queue->cwrite_buf[usent],
1396 queue->cwrite_off - usent);
1397 reschedule_queue_timeout (queue);
1399 /* can we encrypt more? (always encrypt full messages, needed
1400 such that #mq_cancel() can work!) */
1401 if (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE)
1404 gcry_cipher_encrypt (queue->out_cipher,
1405 &queue->cwrite_buf[queue->cwrite_off],
1408 queue->pwrite_off));
1409 if (queue->rekey_left_bytes > queue->pwrite_off)
1410 queue->rekey_left_bytes -= queue->pwrite_off;
1412 queue->rekey_left_bytes = 0;
1413 queue->cwrite_off += queue->pwrite_off;
1414 queue->pwrite_off = 0;
1416 if ( (GNUNET_YES == queue->rekey_state) &&
1417 (0 == queue->pwrite_off) )
1419 if ( (0 == queue->pwrite_off) &&
1420 ( (0 == queue->rekey_left_bytes) ||
1421 (0 == GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us) ) )
1422 inject_rekey (queue);
1423 if ( (0 == queue->pwrite_off) &&
1424 (! queue->finishing) &&
1425 (queue->mq_awaits_continue) )
1427 queue->mq_awaits_continue = GNUNET_NO;
1428 GNUNET_MQ_impl_send_continue (queue->mq);
1430 /* did we just finish writing 'finish'? */
1431 if ( (0 == queue->cwrite_off) &&
1432 (GNUNET_YES == queue->finishing) )
1434 queue_destroy (queue);
1437 /* do we care to write more? */
1438 if (0 < queue->cwrite_off)
1440 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1448 * Signature of functions implementing the sending functionality of a
1451 * @param mq the message queue
1452 * @param msg the message to send
1453 * @param impl_state our `struct Queue`
1456 mq_send (struct GNUNET_MQ_Handle *mq,
1457 const struct GNUNET_MessageHeader *msg,
1460 struct Queue *queue = impl_state;
1461 uint16_t msize = ntohs (msg->size);
1464 GNUNET_assert (mq == queue->mq);
1465 if (GNUNET_YES == queue->finishing)
1466 return; /* this queue is dying, drop msg */
1467 GNUNET_assert (0 == queue->pread_off);
1468 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
1469 box.header.size = htons (msize);
1470 hmac (&queue->out_hmac,
1474 memcpy (&queue->pread_buf[queue->pread_off],
1477 queue->pread_off += sizeof (box);
1478 memcpy (&queue->pread_buf[queue->pread_off],
1481 queue->pread_off += msize;
1482 GNUNET_assert (NULL != queue->sock);
1483 if (NULL == queue->write_task)
1485 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1493 * Signature of functions implementing the destruction of a message
1494 * queue. Implementations must not free @a mq, but should take care
1497 * @param mq the message queue to destroy
1498 * @param impl_state our `struct Queue`
1501 mq_destroy (struct GNUNET_MQ_Handle *mq,
1504 struct Queue *queue = impl_state;
1506 if (mq == queue->mq)
1509 queue_finish (queue);
1515 * Implementation function that cancels the currently sent message.
1517 * @param mq message queue
1518 * @param impl_state our `struct Queue`
1521 mq_cancel (struct GNUNET_MQ_Handle *mq,
1524 struct Queue *queue = impl_state;
1526 GNUNET_assert (0 != queue->pwrite_off);
1527 queue->pwrite_off = 0;
1532 * Generic error handler, called with the appropriate
1533 * error code and the same closure specified at the creation of
1534 * the message queue.
1535 * Not every message queue implementation supports an error handler.
1537 * @param cls our `struct Queue`
1538 * @param error error code
1541 mq_error (void *cls,
1542 enum GNUNET_MQ_Error error)
1544 struct Queue *queue = cls;
1546 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1547 "MQ error in queue to %s: %d\n",
1548 GNUNET_i2s (&queue->target),
1550 queue_finish (queue);
1555 * Add the given @a queue to our internal data structure. Setup the
1556 * MQ processing and inform transport that the queue is ready. Must
1557 * be called after the KX for outgoing messages has been bootstrapped.
1559 * @param queue queue to boot
1562 boot_queue (struct Queue *queue,
1563 enum GNUNET_TRANSPORT_ConnectionStatus cs)
1565 queue->nt = GNUNET_NT_scanner_get_type (is,
1567 queue->address_len);
1568 (void) GNUNET_CONTAINER_multipeermap_put (queue_map,
1571 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1572 GNUNET_STATISTICS_set (stats,
1574 GNUNET_CONTAINER_multipeermap_size (queue_map),
1577 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1579 = GNUNET_MQ_queue_for_callbacks (&mq_send,
1589 switch (queue->address->sa_family)
1592 GNUNET_asprintf (&foreign_addr,
1594 COMMUNICATOR_ADDRESS_PREFIX,
1595 GNUNET_a2s(queue->address,
1596 queue->address_len));
1599 GNUNET_asprintf (&foreign_addr,
1601 COMMUNICATOR_ADDRESS_PREFIX,
1602 GNUNET_a2s(queue->address,
1603 queue->address_len));
1609 = GNUNET_TRANSPORT_communicator_mq_add (ch,
1616 GNUNET_free (foreign_addr);
1622 * Generate and transmit our ephemeral key and the signature for
1623 * the initial KX with the other peer. Must be called first, before
1624 * any other bytes are ever written to the output buffer. Note that
1625 * our cipher must already be initialized when calling this function.
1626 * Helper function for #start_initial_kx_out().
1628 * @param queue queue to do KX for
1629 * @param epub our public key for the KX
1632 transmit_kx (struct Queue *queue,
1633 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1635 struct TcpHandshakeSignature ths;
1636 struct TCPConfirmation tc;
1638 memcpy (queue->cwrite_buf,
1641 queue->cwrite_off = sizeof (epub);
1642 /* compute 'tc' and append in encrypted format to cwrite_buf */
1643 tc.sender = my_identity;
1644 tc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1645 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1646 ths.purpose.size = htonl (sizeof (ths));
1647 ths.sender = my_identity;
1648 ths.receiver = queue->target;
1649 ths.ephemeral = *epub;
1650 ths.monotonic_time = tc.monotonic_time;
1651 GNUNET_assert (GNUNET_OK ==
1652 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1656 gcry_cipher_encrypt (queue->out_cipher,
1657 &queue->cwrite_buf[queue->cwrite_off],
1661 queue->cwrite_off += sizeof (tc);
1666 * Initialize our key material for outgoing transmissions and
1667 * inform the other peer about it. Must be called first before
1670 * @param queue the queue to setup
1673 start_initial_kx_out (struct Queue *queue)
1675 struct GNUNET_CRYPTO_EcdhePublicKey epub;
1677 GNUNET_assert (GNUNET_OK ==
1678 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1679 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1681 setup_out_cipher (queue);
1688 * We have received the first bytes from the other side on a @a queue.
1689 * Decrypt the @a tc contained in @a ibuf and check the signature.
1690 * Note that #setup_in_cipher() must have already been called.
1692 * @param queue queue to decrypt initial bytes from other peer for
1693 * @param tc[out] where to store the result
1694 * @param ibuf incoming data, of size
1696 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
1699 decrypt_and_check_tc (struct Queue *queue,
1700 struct TCPConfirmation *tc,
1703 struct TcpHandshakeSignature ths;
1706 gcry_cipher_decrypt (queue->in_cipher,
1709 &ibuf[sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)],
1711 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1712 ths.purpose.size = htonl (sizeof (ths));
1713 ths.sender = tc->sender;
1714 ths.receiver = my_identity;
1715 memcpy (&ths.ephemeral,
1717 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1718 ths.monotonic_time = tc->monotonic_time;
1719 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
1722 &tc->sender.public_key);
1727 * Closes socket and frees memory associated with @a pq.
1729 * @param pq proto queue to free
1732 free_proto_queue (struct ProtoQueue *pq)
1734 GNUNET_NETWORK_socket_close (pq->sock);
1735 GNUNET_free (pq->address);
1736 GNUNET_CONTAINER_DLL_remove (proto_head,
1744 * Read from the socket of the proto queue until we have enough data
1745 * to upgrade to full queue.
1747 * @param cls a `struct ProtoQueue`
1750 proto_read_kx (void *cls)
1752 struct ProtoQueue *pq = cls;
1754 struct GNUNET_TIME_Relative left;
1755 struct Queue *queue;
1756 struct TCPConfirmation tc;
1758 pq->read_task = NULL;
1759 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
1760 if (0 == left.rel_value_us)
1762 free_proto_queue (pq);
1765 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
1766 &pq->ibuf[pq->ibuf_off],
1767 sizeof (pq->ibuf) - pq->ibuf_off);
1770 if ( (EAGAIN != errno) &&
1773 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1775 free_proto_queue (pq);
1779 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1785 pq->ibuf_off += rcvd;
1786 if (pq->ibuf_off > sizeof (pq->ibuf))
1789 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1795 /* we got all the data, let's find out who we are talking to! */
1796 queue = GNUNET_new (struct Queue);
1797 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
1800 decrypt_and_check_tc (queue,
1804 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1805 "Invalid TCP KX received from %s\n",
1806 GNUNET_a2s (queue->address,
1807 queue->address_len));
1808 gcry_cipher_close (queue->in_cipher);
1809 GNUNET_free (queue);
1810 free_proto_queue (pq);
1813 queue->address = pq->address; /* steals reference */
1814 queue->address_len = pq->address_len;
1815 queue->target = tc.sender;
1816 start_initial_kx_out (queue);
1818 GNUNET_TRANSPORT_CS_INBOUND);
1820 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1824 GNUNET_CONTAINER_DLL_remove (proto_head,
1832 * We have been notified that our listen socket has something to
1833 * read. Do the read and reschedule this function to be called again
1834 * once more is available.
1839 listen_cb (void *cls)
1841 struct sockaddr_storage in;
1843 struct GNUNET_NETWORK_Handle *sock;
1844 struct ProtoQueue *pq;
1847 GNUNET_assert (NULL != listen_sock);
1848 addrlen = sizeof (in);
1852 sock = GNUNET_NETWORK_socket_accept (listen_sock,
1853 (struct sockaddr *) &in,
1855 if ( (NULL == sock) &&
1856 ( (EMFILE == errno) ||
1857 (ENFILE == errno) ) )
1858 return; /* system limit reached, wait until connection goes down */
1859 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1863 if ( (NULL == sock) &&
1864 ( (EAGAIN == errno) ||
1865 (ENOBUFS == errno) ) )
1869 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1873 pq = GNUNET_new (struct ProtoQueue);
1874 pq->address_len = addrlen;
1875 pq->address = GNUNET_memdup (&in,
1877 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
1879 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
1883 GNUNET_CONTAINER_DLL_insert (proto_head,
1890 * Read from the socket of the queue until we have enough data
1891 * to initialize the decryption logic and can switch to regular
1894 * @param cls a `struct Queue`
1897 queue_read_kx (void *cls)
1899 struct Queue *queue = cls;
1901 struct GNUNET_TIME_Relative left;
1902 struct TCPConfirmation tc;
1904 queue->read_task = NULL;
1905 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1906 if (0 == left.rel_value_us)
1908 queue_destroy (queue);
1911 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1912 &queue->cread_buf[queue->cread_off],
1913 BUF_SIZE - queue->cread_off);
1916 if ( (EAGAIN != errno) &&
1919 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1921 queue_destroy (queue);
1924 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1930 queue->cread_off += rcvd;
1931 if (queue->cread_off <
1935 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1941 /* we got all the data, let's find out who we are talking to! */
1942 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) queue->cread_buf,
1945 decrypt_and_check_tc (queue,
1949 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1950 "Invalid TCP KX received from %s\n",
1951 GNUNET_a2s (queue->address,
1952 queue->address_len));
1953 queue_destroy (queue);
1956 if (0 != memcmp (&tc.sender,
1958 sizeof (struct GNUNET_PeerIdentity)))
1960 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1961 "Invalid sender in TCP KX received from %s\n",
1962 GNUNET_a2s (queue->address,
1963 queue->address_len));
1964 queue_destroy (queue);
1968 /* update queue timeout */
1969 reschedule_queue_timeout (queue);
1970 /* prepare to continue with regular read task immediately */
1971 memmove (queue->cread_buf,
1972 &queue->cread_buf[INITIAL_KX_SIZE],
1973 queue->cread_off - (INITIAL_KX_SIZE));
1974 queue->cread_off -= INITIAL_KX_SIZE;
1975 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read,
1981 * Function called by the transport service to initialize a
1982 * message queue given address information about another peer.
1983 * If and when the communication channel is established, the
1984 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
1985 * to notify the service that the channel is now up. It is
1986 * the responsibility of the communicator to manage sane
1987 * retries and timeouts for any @a peer/@a address combination
1988 * provided by the transport service. Timeouts and retries
1989 * do not need to be signalled to the transport service.
1991 * @param cls closure
1992 * @param peer identity of the other peer
1993 * @param address where to send the message, human-readable
1994 * communicator-specific format, 0-terminated, UTF-8
1995 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
1999 const struct GNUNET_PeerIdentity *peer,
2000 const char *address)
2002 struct Queue *queue;
2004 struct sockaddr *in;
2006 struct GNUNET_NETWORK_Handle *sock;
2008 if (0 != strncmp (address,
2009 COMMUNICATOR_ADDRESS_PREFIX "-",
2010 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2012 GNUNET_break_op (0);
2013 return GNUNET_SYSERR;
2015 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2016 in = tcp_address_to_sockaddr (path,
2019 sock = GNUNET_NETWORK_socket_create (in->sa_family,
2024 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2025 "socket(%d) failed: %s",
2029 return GNUNET_SYSERR;
2032 GNUNET_NETWORK_socket_connect (sock,
2036 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2037 "connect to `%s' failed: %s",
2040 GNUNET_NETWORK_socket_close (sock);
2042 return GNUNET_SYSERR;
2045 queue = GNUNET_new (struct Queue);
2046 queue->target = *peer;
2047 queue->address = in;
2048 queue->address_len = in_len;
2051 GNUNET_TRANSPORT_CS_OUTBOUND);
2053 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2059 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2060 "Failed to setup queue to %s at `%s'\n",
2063 GNUNET_NETWORK_socket_close (sock);
2066 start_initial_kx_out (queue);
2072 * Iterator over all message queues to clean up.
2075 * @param target unused
2076 * @param value the queue to destroy
2077 * @return #GNUNET_OK to continue to iterate
2080 get_queue_delete_it (void *cls,
2081 const struct GNUNET_PeerIdentity *target,
2084 struct Queue *queue = value;
2088 queue_destroy (queue);
2094 * Shutdown the UNIX communicator.
2096 * @param cls NULL (always)
2099 do_shutdown (void *cls)
2103 GNUNET_NAT_unregister (nat);
2106 if (NULL != listen_task)
2108 GNUNET_SCHEDULER_cancel (listen_task);
2111 if (NULL != listen_sock)
2113 GNUNET_break (GNUNET_OK ==
2114 GNUNET_NETWORK_socket_close (listen_sock));
2117 GNUNET_CONTAINER_multipeermap_iterate (queue_map,
2118 &get_queue_delete_it,
2120 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
2123 GNUNET_TRANSPORT_communicator_disconnect (ch);
2128 GNUNET_STATISTICS_destroy (stats,
2132 if (NULL != my_private_key)
2134 GNUNET_free (my_private_key);
2135 my_private_key = NULL;
2139 GNUNET_NT_scanner_done (is);
2146 * Function called when the transport service has received an
2147 * acknowledgement for this communicator (!) via a different return
2150 * Not applicable for TCP.
2152 * @param cls closure
2153 * @param sender which peer sent the notification
2154 * @param msg payload
2157 enc_notify_cb (void *cls,
2158 const struct GNUNET_PeerIdentity *sender,
2159 const struct GNUNET_MessageHeader *msg)
2164 GNUNET_break_op (0);
2169 * Signature of the callback passed to #GNUNET_NAT_register() for
2170 * a function to call whenever our set of 'valid' addresses changes.
2172 * @param cls closure
2173 * @param app_ctx[in,out] location where the app can store stuff
2174 * on add and retrieve it on remove
2175 * @param add_remove #GNUNET_YES to add a new public IP address,
2176 * #GNUNET_NO to remove a previous (now invalid) one
2177 * @param ac address class the address belongs to
2178 * @param addr either the previous or the new public IP address
2179 * @param addrlen actual length of the @a addr
2182 nat_address_cb (void *cls,
2185 enum GNUNET_NAT_AddressClass ac,
2186 const struct sockaddr *addr,
2190 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
2192 if (GNUNET_YES == add_remove)
2194 enum GNUNET_NetworkType nt;
2196 GNUNET_asprintf (&my_addr,
2198 COMMUNICATOR_ADDRESS_PREFIX,
2201 nt = GNUNET_NT_scanner_get_type (is,
2204 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2207 GNUNET_TIME_UNIT_FOREVER_REL);
2208 GNUNET_free (my_addr);
2214 GNUNET_TRANSPORT_communicator_address_remove (ai);
2221 * Setup communicator and launch network interactions.
2223 * @param cls NULL (always)
2224 * @param args remaining command-line arguments
2225 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2226 * @param c configuration
2231 const char *cfgfile,
2232 const struct GNUNET_CONFIGURATION_Handle *c)
2235 struct sockaddr *in;
2237 struct sockaddr_storage in_sto;
2243 GNUNET_CONFIGURATION_get_value_filename (cfg,
2244 COMMUNICATOR_CONFIG_SECTION,
2248 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2249 COMMUNICATOR_CONFIG_SECTION,
2254 GNUNET_CONFIGURATION_get_value_number (cfg,
2255 COMMUNICATOR_CONFIG_SECTION,
2258 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2260 in = tcp_address_to_sockaddr (bindto,
2264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2265 "Failed to setup TCP socket address with path `%s'\n",
2267 GNUNET_free (bindto);
2270 listen_sock = GNUNET_NETWORK_socket_create (in->sa_family,
2273 if (NULL == listen_sock)
2275 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2278 GNUNET_free (bindto);
2282 GNUNET_NETWORK_socket_bind (listen_sock,
2286 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2289 GNUNET_NETWORK_socket_close (listen_sock);
2292 GNUNET_free (bindto);
2295 /* We might have bound to port 0, allowing the OS to figure it out;
2296 thus, get the real IN-address from the socket */
2297 sto_len = sizeof (in_sto);
2298 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
2299 (struct sockaddr *) &in_sto,
2308 GNUNET_free (bindto);
2309 in = (struct sockaddr *) &in_sto;
2311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2313 GNUNET_a2s ((const struct sockaddr *) &in_sto,
2315 stats = GNUNET_STATISTICS_create ("C-TCP",
2317 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
2319 is = GNUNET_NT_scanner_init ();
2320 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2321 if (NULL == my_private_key)
2323 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2324 _("Transport service is lacking key configuration settings. Exiting.\n"));
2325 GNUNET_SCHEDULER_shutdown ();
2328 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
2329 &my_identity.public_key);
2330 /* start listening */
2331 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2335 queue_map = GNUNET_CONTAINER_multipeermap_create (10,
2337 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2338 COMMUNICATOR_CONFIG_SECTION,
2339 COMMUNICATOR_ADDRESS_PREFIX,
2340 GNUNET_TRANSPORT_CC_RELIABLE,
2348 GNUNET_SCHEDULER_shutdown ();
2351 nat = GNUNET_NAT_register (cfg,
2352 COMMUNICATOR_CONFIG_SECTION,
2354 1 /* one address */,
2355 (const struct sockaddr **) &in,
2358 NULL /* FIXME: support reversal: #5529 */,
2359 NULL /* closure */);
2364 * The main function for the UNIX communicator.
2366 * @param argc number of arguments from the command line
2367 * @param argv command line arguments
2368 * @return 0 ok, 1 on error
2374 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2375 GNUNET_GETOPT_OPTION_END
2380 GNUNET_STRINGS_get_utf8_args (argc, argv,
2386 GNUNET_PROGRAM_run (argc, argv,
2387 "gnunet-communicator-tcp",
2388 _("GNUnet TCP communicator"),
2392 GNUNET_free ((void*) argv);
2397 /* end of gnunet-communicator-tcp.c */