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 * - NAT service API change to handle address stops!
28 * - address construction for HELLOs (FIXMEs, easy)
31 #include "gnunet_util_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_signatures.h"
34 #include "gnunet_constants.h"
35 #include "gnunet_nt_lib.h"
36 #include "gnunet_nat_service.h"
37 #include "gnunet_statistics_service.h"
38 #include "gnunet_transport_communication_service.h"
41 * How many messages do we keep at most in the queue to the
42 * transport service before we start to drop (default,
43 * can be changed via the configuration file).
44 * Should be _below_ the level of the communicator API, as
45 * otherwise we may read messages just to have them dropped
46 * by the communicator API.
48 #define DEFAULT_MAX_QUEUE_LENGTH 8
51 * Size of our IO buffers for ciphertext data. Must be at
52 * least UINT_MAX + sizeof (struct TCPBox).
54 #define BUF_SIZE (2 * 64 * 1024 + sizeof (struct TCPBox))
57 * How often do we rekey based on time (at least)
59 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
62 * How long do we wait until we must have received the initial KX?
64 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
67 * How often do we rekey based on number of bytes transmitted?
68 * (additionally randomized).
70 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
73 * Size of the initial key exchange message sent first in both
76 #define INITIAL_KX_SIZE (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof (struct TCPConfirmation))
80 * Address prefix used by the communicator.
82 #define COMMUNICATOR_ADDRESS_PREFIX "tcp"
85 * Configuration section used by the communicator.
87 #define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
89 GNUNET_NETWORK_STRUCT_BEGIN
93 * Signature we use to verify that the ephemeral key was really chosen by
94 * the specified sender.
96 struct TcpHandshakeSignature
99 * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
101 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
104 * Identity of the inititor of the TCP connection (TCP client).
106 struct GNUNET_PeerIdentity sender;
109 * Presumed identity of the target of the TCP connection (TCP server)
111 struct GNUNET_PeerIdentity receiver;
114 * Ephemeral key used by the @e sender.
116 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
119 * Monotonic time of @e sender, to possibly help detect replay attacks
120 * (if receiver persists times by sender).
122 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
127 * Encrypted continuation of TCP initial handshake.
129 struct TCPConfirmation
134 struct GNUNET_PeerIdentity sender;
137 * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
139 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
142 * Monotonic time of @e sender, to possibly help detect replay attacks
143 * (if receiver persists times by sender).
145 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
151 * TCP message box. Always sent encrypted!
157 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX. Warning: the
158 * header size EXCLUDES the size of the `struct TCPBox`. We usually
159 * never do this, but here the payload may truly be 64k *after* the
160 * TCPBox (as we have no MTU)!!
162 struct GNUNET_MessageHeader header;
165 * HMAC for the following encrypted message. Yes, we MUST use
166 * mac-then-encrypt here, as we want to hide the message sizes on
167 * the wire (zero plaintext design!). Using CTR mode padding oracle
168 * attacks do not apply. Besides, due to the use of ephemeral keys
169 * (hopefully with effective replay protection from monotonic time!)
170 * the attacker is limited in using the oracle.
172 struct GNUNET_ShortHashCode hmac;
174 /* followed by as may bytes of payload as indicated in @e header,
175 excluding the TCPBox itself! */
181 * TCP rekey message box. Always sent encrypted! Data after
182 * this message will use the new key.
188 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
190 struct GNUNET_MessageHeader header;
193 * HMAC for the following encrypted message. Yes, we MUST use
194 * mac-then-encrypt here, as we want to hide the message sizes on
195 * the wire (zero plaintext design!). Using CTR mode padding oracle
196 * attacks do not apply. Besides, due to the use of ephemeral keys
197 * (hopefully with effective replay protection from monotonic time!)
198 * the attacker is limited in using the oracle.
200 struct GNUNET_ShortHashCode hmac;
205 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
208 * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY
210 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
213 * Monotonic time of @e sender, to possibly help detect replay attacks
214 * (if receiver persists times by sender).
216 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
222 * TCP finish. Sender asks for the connection to be closed.
223 * Needed/useful in case we drop RST/FIN packets on the GNUnet
224 * port due to the possibility of malicious RST/FIN injection.
230 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
232 struct GNUNET_MessageHeader header;
235 * HMAC for the following encrypted message. Yes, we MUST use
236 * mac-then-encrypt here, as we want to hide the message sizes on
237 * the wire (zero plaintext design!). Using CTR mode padding oracle
238 * attacks do not apply. Besides, due to the use of ephemeral keys
239 * (hopefully with effective replay protection from monotonic time!)
240 * the attacker is limited in using the oracle.
242 struct GNUNET_ShortHashCode hmac;
247 GNUNET_NETWORK_STRUCT_END
251 * Handle for a queue.
257 * To whom are we talking to.
259 struct GNUNET_PeerIdentity target;
262 * socket that we transmit all data with on this queue
264 struct GNUNET_NETWORK_Handle *sock;
267 * cipher for decryption of incoming data.
269 gcry_cipher_hd_t in_cipher;
272 * cipher for encryption of outgoing data.
274 gcry_cipher_hd_t out_cipher;
277 * Shared secret for HMAC verification on incoming data.
279 struct GNUNET_HashCode in_hmac;
282 * Shared secret for HMAC generation on outgoing data, ratcheted after
285 struct GNUNET_HashCode out_hmac;
288 * Our ephemeral key. Stored here temporarily during rekeying / key generation.
290 struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral;
293 * ID of read task for this connection.
295 struct GNUNET_SCHEDULER_Task *read_task;
298 * ID of write task for this connection.
300 struct GNUNET_SCHEDULER_Task *write_task;
303 * Address of the other peer.
305 struct sockaddr *address;
308 * How many more bytes may we sent with the current @e out_cipher
309 * before we should rekey?
311 uint64_t rekey_left_bytes;
314 * Until what time may we sent with the current @e out_cipher
315 * before we should rekey?
317 struct GNUNET_TIME_Absolute rekey_time;
320 * Length of the address.
322 socklen_t address_len;
325 * Message queue we are providing for the #ch.
327 struct GNUNET_MQ_Handle *mq;
330 * handle for this queue with the #ch.
332 struct GNUNET_TRANSPORT_QueueHandle *qh;
335 * Number of bytes we currently have in our write queue.
337 unsigned long long bytes_in_queue;
340 * Buffer for reading ciphertext from network into.
342 char cread_buf[BUF_SIZE];
345 * buffer for writing ciphertext to network.
347 char cwrite_buf[BUF_SIZE];
350 * Plaintext buffer for decrypted plaintext.
352 char pread_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
355 * Plaintext buffer for messages to be encrypted.
357 char pwrite_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
360 * At which offset in the ciphertext read buffer should we
361 * append more ciphertext for transmission next?
366 * At which offset in the ciphertext write buffer should we
367 * append more ciphertext from reading next?
372 * At which offset in the plaintext input buffer should we
373 * append more plaintext from decryption next?
378 * At which offset in the plaintext output buffer should we
379 * append more plaintext for encryption next?
384 * Timeout for this queue.
386 struct GNUNET_TIME_Absolute timeout;
389 * How may messages did we pass from this queue to CORE for which we
390 * have yet to receive an acknoweldgement that CORE is done with
391 * them? If "large" (or even just non-zero), we should throttle
392 * reading to provide flow control. See also #DEFAULT_MAX_QUEUE_LENGTH
393 * and #max_queue_length.
395 unsigned int backpressure;
398 * Which network type does this queue use?
400 enum GNUNET_NetworkType nt;
403 * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call?
405 int mq_awaits_continue;
408 * Did we enqueue a finish message and are closing down the queue?
413 * Did we technically destroy this queue, but kept the allocation
414 * around because of @e backpressure not being zero yet? Used
415 * simply to delay the final #GNUNET_free() operation until
416 * #core_read_finished_cb() has been called.
421 * #GNUNET_YES after #inject_key() placed the rekey message into the
422 * plaintext buffer. Once the plaintext buffer is drained, this
423 * means we must switch to the new key material.
428 * #GNUNET_YES if we just rekeyed and must thus possibly
429 * re-decrypt ciphertext.
436 * Handle for an incoming connection where we do not yet have enough
437 * information to setup a full queue.
445 struct ProtoQueue *next;
450 struct ProtoQueue *prev;
453 * socket that we transmit all data with on this queue
455 struct GNUNET_NETWORK_Handle *sock;
458 * ID of read task for this connection.
460 struct GNUNET_SCHEDULER_Task *read_task;
463 * Address of the other peer.
465 struct sockaddr *address;
468 * Length of the address.
470 socklen_t address_len;
473 * Timeout for this protoqueue.
475 struct GNUNET_TIME_Absolute timeout;
478 * Buffer for reading all the information we need to upgrade from
479 * protoqueue to queue.
481 char ibuf[INITIAL_KX_SIZE];
484 * Current offset for reading into @e ibuf.
493 static struct GNUNET_SCHEDULER_Task *listen_task;
496 * Maximum queue length before we stop reading towards the transport service.
498 static unsigned long long max_queue_length;
501 * For logging statistics.
503 static struct GNUNET_STATISTICS_Handle *stats;
508 static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
511 * Queues (map from peer identity to `struct Queue`)
513 static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
518 static struct GNUNET_NETWORK_Handle *listen_sock;
523 static struct GNUNET_PeerIdentity my_identity;
528 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
533 static const struct GNUNET_CONFIGURATION_Handle *cfg;
536 * Network scanner to determine network types.
538 static struct GNUNET_NT_InterfaceScanner *is;
541 * Connection to NAT service.
543 static struct GNUNET_NAT_Handle *nat;
546 * Protoqueues DLL head.
548 static struct ProtoQueue *proto_head;
551 * Protoqueues DLL tail.
553 static struct ProtoQueue *proto_tail;
557 * We have been notified that our listen socket has something to
558 * read. Do the read and reschedule this function to be called again
559 * once more is available.
564 listen_cb (void *cls);
568 * Functions with this signature are called whenever we need
569 * to close a queue due to a disconnect or failure to
570 * establish a connection.
572 * @param queue queue to close down
575 queue_destroy (struct Queue *queue)
577 struct GNUNET_MQ_Handle *mq;
579 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
580 "Disconnecting queue for peer `%s'\n",
581 GNUNET_i2s (&queue->target));
582 if (NULL != (mq = queue->mq))
585 GNUNET_MQ_destroy (mq);
587 GNUNET_assert (GNUNET_YES ==
588 GNUNET_CONTAINER_multipeermap_remove (queue_map,
591 GNUNET_STATISTICS_set (stats,
593 GNUNET_CONTAINER_multipeermap_size (queue_map),
595 if (NULL != queue->read_task)
597 GNUNET_SCHEDULER_cancel (queue->read_task);
598 queue->read_task = NULL;
600 if (NULL != queue->write_task)
602 GNUNET_SCHEDULER_cancel (queue->write_task);
603 queue->write_task = NULL;
605 GNUNET_NETWORK_socket_close (queue->sock);
606 gcry_cipher_close (queue->in_cipher);
607 gcry_cipher_close (queue->out_cipher);
608 GNUNET_free (queue->address);
609 if (0 != queue->backpressure)
610 queue->destroyed = GNUNET_YES;
613 if (NULL == listen_task)
614 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
622 * Compute @a mac over @a buf, and ratched the @a hmac_secret.
624 * @param[in,out] hmac_secret secret for HMAC calculation
625 * @param buf buffer to MAC
626 * @param buf_size number of bytes in @a buf
627 * @param smac[out] where to write the HMAC
630 hmac (struct GNUNET_HashCode *hmac_secret,
633 struct GNUNET_ShortHashCode *smac)
635 struct GNUNET_HashCode mac;
637 GNUNET_CRYPTO_hmac_raw (hmac_secret,
638 sizeof (struct GNUNET_HashCode),
642 /* truncate to `struct GNUNET_ShortHashCode` */
645 sizeof (struct GNUNET_ShortHashCode));
646 /* ratchet hmac key */
647 GNUNET_CRYPTO_hash (hmac_secret,
648 sizeof (struct GNUNET_HashCode),
654 * Append a 'finish' message to the outgoing transmission. Once the
655 * finish has been transmitted, destroy the queue.
657 * @param queue queue to shut down nicely
660 queue_finish (struct Queue *queue)
662 struct TCPFinish fin;
667 fin.header.size = htons (sizeof (fin));
668 fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
669 hmac (&queue->out_hmac,
673 /* if there is any message left in pwrite_buf, we
674 overwrite it (possibly dropping the last message
675 from CORE hard here) */
676 memcpy (queue->pwrite_buf,
679 queue->pwrite_off = sizeof (fin);
680 /* This flag will ensure that #queue_write() no longer
681 notifies CORE about the possibility of sending
682 more data, and that #queue_write() will call
683 #queue_destroy() once the @c fin was fully written. */
684 queue->finishing = GNUNET_YES;
689 * Increment queue timeout due to activity. We do not immediately
690 * notify the monitor here as that might generate excessive
693 * @param queue queue for which the timeout should be rescheduled
696 reschedule_queue_timeout (struct Queue *queue)
699 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
704 * Queue read task. If we hit the timeout, disconnect it
706 * @param cls the `struct Queue *` to disconnect
709 queue_read (void *cls);
713 * Core tells us it is done processing a message that transport
714 * received on a queue with status @a success.
716 * @param cls a `struct Queue *` where the message originally came from
717 * @param success #GNUNET_OK on success
720 core_read_finished_cb (void *cls,
723 struct Queue *queue = cls;
725 if (GNUNET_OK != success)
726 GNUNET_STATISTICS_update (stats,
727 "# messages lost in communicator API towards CORE",
730 queue->backpressure--;
731 /* handle deferred queue destruction */
732 if ( (queue->destroyed) &&
733 (0 == queue->backpressure) )
738 reschedule_queue_timeout (queue);
739 /* possibly unchoke reading, now that CORE made progress */
740 if (NULL == queue->read_task)
742 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (queue->timeout),
750 * We received @a plaintext_len bytes of @a plaintext on @a queue.
751 * Pass it on to CORE. If transmission is actually happening,
752 * increase backpressure counter.
754 * @param queue the queue that received the plaintext
755 * @param plaintext the plaintext that was received
756 * @param plaintext_len number of bytes of plaintext received
759 pass_plaintext_to_core (struct Queue *queue,
760 const void *plaintext,
761 size_t plaintext_len)
763 const struct GNUNET_MessageHeader *hdr = plaintext;
766 if (ntohs (hdr->size) != plaintext_len)
768 /* NOTE: If we ever allow multiple CORE messages in one
769 BOX, this will have to change! */
773 ret = GNUNET_TRANSPORT_communicator_receive (ch,
776 &core_read_finished_cb,
778 if (GNUNET_OK == ret)
779 queue->backpressure++;
780 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
781 if (GNUNET_SYSERR == ret)
782 GNUNET_STATISTICS_update (stats,
783 "# bytes lost due to CORE not running",
790 * Setup @a cipher based on shared secret @a dh and decrypting
793 * @param dh shared secret
794 * @param pid decrypting peer's identity
795 * @param cipher[out] cipher to initialize
796 * @param hmac_key[out] HMAC key to initialize
799 setup_cipher (const struct GNUNET_HashCode *dh,
800 const struct GNUNET_PeerIdentity *pid,
801 gcry_cipher_hd_t *cipher,
802 struct GNUNET_HashCode *hmac_key)
807 gcry_cipher_open (cipher,
808 GCRY_CIPHER_AES256 /* low level: go for speed */,
809 GCRY_CIPHER_MODE_CTR,
811 GNUNET_assert (GNUNET_YES ==
812 GNUNET_CRYPTO_kdf (key,
821 gcry_cipher_setkey (*cipher,
824 GNUNET_assert (GNUNET_YES ==
825 GNUNET_CRYPTO_kdf (ctr,
834 gcry_cipher_setctr (*cipher,
837 GNUNET_assert (GNUNET_YES ==
838 GNUNET_CRYPTO_kdf (hmac_key,
839 sizeof (struct GNUNET_HashCode),
851 * Setup cipher of @a queue for decryption.
853 * @param ephemeral ephemeral key we received from the other peer
854 * @param queue[in,out] queue to initialize decryption cipher for
857 setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
860 struct GNUNET_HashCode dh;
862 GNUNET_CRYPTO_eddsa_ecdh (my_private_key,
873 * Handle @a rekey message on @a queue. The message was already
874 * HMAC'ed, but we should additionally still check the signature.
875 * Then we need to stop the old cipher and start afresh.
877 * @param queue the queue @a rekey was received on
878 * @param rekey the rekey message
881 do_rekey (struct Queue *queue,
882 const struct TCPRekey *rekey)
884 struct TcpHandshakeSignature thp;
886 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
887 thp.purpose.size = htonl (sizeof (thp));
888 thp.sender = queue->target;
889 thp.receiver = my_identity;
890 thp.ephemeral = rekey->ephemeral;
891 thp.monotonic_time = rekey->monotonic_time;
893 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY,
896 &queue->target.public_key))
899 queue_finish (queue);
902 gcry_cipher_close (queue->in_cipher);
903 queue->rekeyed = GNUNET_YES;
904 setup_in_cipher (&rekey->ephemeral,
910 * Test if we have received a full message in plaintext.
913 * @param queue queue to process inbound plaintext for
914 * @return number of bytes of plaintext handled, 0 for none
917 try_handle_plaintext (struct Queue *queue)
919 const struct GNUNET_MessageHeader *hdr
920 = (const struct GNUNET_MessageHeader *) queue->pread_buf;
921 const struct TCPBox *box
922 = (const struct TCPBox *) queue->pread_buf;
923 const struct TCPRekey *rekey
924 = (const struct TCPRekey *) queue->pread_buf;
925 const struct TCPFinish *fin
926 = (const struct TCPFinish *) queue->pread_buf;
927 struct TCPRekey rekeyz;
928 struct TCPFinish finz;
929 struct GNUNET_ShortHashCode tmac;
931 size_t size = 0; /* make compiler happy */
933 if (sizeof (*hdr) > queue->pread_off)
934 return 0; /* not even a header */
935 type = ntohs (hdr->type);
938 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
939 /* Special case: header size excludes box itself! */
940 if (ntohs (hdr->size) + sizeof (struct TCPBox) > queue->pread_off)
942 hmac (&queue->in_hmac,
946 if (0 != memcmp (&tmac,
951 queue_finish (queue);
954 pass_plaintext_to_core (queue,
955 (const void *) &box[1],
957 size = ntohs (hdr->size) + sizeof (*box);
959 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
960 if (sizeof (*rekey) > queue->pread_off)
962 if (ntohs (hdr->size) != sizeof (*rekey))
965 queue_finish (queue);
969 memset (&rekeyz.hmac,
971 sizeof (rekeyz.hmac));
972 hmac (&queue->in_hmac,
976 if (0 != memcmp (&tmac,
981 queue_finish (queue);
986 size = ntohs (hdr->size);
988 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
989 if (sizeof (*fin) > queue->pread_off)
991 if (ntohs (hdr->size) != sizeof (*fin))
994 queue_finish (queue);
1000 sizeof (finz.hmac));
1001 hmac (&queue->in_hmac,
1005 if (0 != memcmp (&tmac,
1009 GNUNET_break_op (0);
1010 queue_finish (queue);
1013 /* handle FINISH by destroying queue */
1014 queue_destroy (queue);
1017 GNUNET_break_op (0);
1018 queue_finish (queue);
1021 GNUNET_assert (0 != size);
1027 * Queue read task. If we hit the timeout, disconnect it
1029 * @param cls the `struct Queue *` to disconnect
1032 queue_read (void *cls)
1034 struct Queue *queue = cls;
1035 struct GNUNET_TIME_Relative left;
1038 queue->read_task = NULL;
1039 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1040 &queue->cread_buf[queue->cread_off],
1041 BUF_SIZE - queue->cread_off);
1044 if ( (EAGAIN != errno) &&
1047 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1049 queue_finish (queue);
1054 = GNUNET_SCHEDULER_add_read_net (left,
1061 reschedule_queue_timeout (queue);
1062 queue->cread_off += rcvd;
1063 while ( (queue->pread_off < sizeof (queue->pread_buf)) &&
1064 (queue->cread_off > 0) )
1066 size_t max = GNUNET_MIN (sizeof (queue->pread_buf) - queue->pread_off,
1072 gcry_cipher_decrypt (queue->in_cipher,
1073 &queue->pread_buf[queue->pread_off],
1077 queue->pread_off += max;
1079 while ( (GNUNET_NO == queue->rekeyed) &&
1080 (0 != (done = try_handle_plaintext (queue))) )
1082 /* 'done' bytes of plaintext were used, shift buffer */
1083 GNUNET_assert (done <= queue->pread_off);
1084 /* NOTE: this memmove() could possibly sometimes be
1085 avoided if we pass 'total' into try_handle_plaintext()
1086 and use it at an offset into the buffer there! */
1087 memmove (queue->pread_buf,
1088 &queue->pread_buf[done],
1089 queue->pread_off - done);
1090 queue->pread_off -= done;
1093 /* when we encounter a rekey message, the decryption above uses the
1094 wrong key for everything after the rekey; in that case, we have
1095 to re-do the decryption at 'total' instead of at 'max'. If there
1096 is no rekey and the last message is incomplete (max > total),
1097 it is safe to keep the decryption so we shift by 'max' */
1098 if (GNUNET_YES == queue->rekeyed)
1101 queue->rekeyed = GNUNET_NO;
1103 memmove (queue->cread_buf,
1104 &queue->cread_buf[max],
1105 queue->cread_off - max);
1106 queue->cread_off -= max;
1109 if (BUF_SIZE == queue->cread_off)
1110 return; /* buffer full, suspend reading */
1111 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1112 if (0 != left.rel_value_us)
1114 if (max_queue_length < queue->backpressure)
1116 /* continue reading */
1118 = GNUNET_SCHEDULER_add_read_net (left,
1125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1126 "Queue %p was idle for %s, disconnecting\n",
1128 GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1130 queue_finish (queue);
1135 * Convert TCP bind specification to a `struct sockaddr *`
1137 * @param bindto bind specification to convert
1138 * @param[out] sock_len set to the length of the address
1139 * @return converted bindto specification
1141 static struct sockaddr *
1142 tcp_address_to_sockaddr (const char *bindto,
1143 socklen_t *sock_len)
1145 struct sockaddr *in;
1151 if (1 == SSCANF (bindto,
1156 /* interpreting value as just a PORT number */
1157 if (port > UINT16_MAX)
1159 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1160 "BINDTO specification `%s' invalid: value too large for port\n",
1165 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1166 COMMUNICATOR_CONFIG_SECTION,
1169 struct sockaddr_in *i4;
1171 i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1172 i4->sin_family = AF_INET;
1173 i4->sin_port = htons ((uint16_t) port);
1174 *sock_len = sizeof (struct sockaddr_in);
1175 in = (struct sockaddr *) i4;
1179 struct sockaddr_in6 *i6;
1181 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1182 i6->sin6_family = AF_INET6;
1183 i6->sin6_port = htons ((uint16_t) port);
1184 *sock_len = sizeof (struct sockaddr_in6);
1185 in = (struct sockaddr *) i6;
1189 cp = GNUNET_strdup (bindto);
1190 colon = strrchr (cp, ':');
1193 /* interpet value after colon as port */
1196 if (1 == SSCANF (colon,
1201 /* interpreting value as just a PORT number */
1202 if (port > UINT16_MAX)
1204 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1205 "BINDTO specification `%s' invalid: value too large for port\n",
1213 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1214 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1222 /* interpret missing port as 0, aka pick any free one */
1227 struct sockaddr_in v4;
1229 if (1 == inet_pton (AF_INET,
1233 v4.sin_port = htons ((uint16_t) port);
1234 in = GNUNET_memdup (&v4,
1236 *sock_len = sizeof (v4);
1243 struct sockaddr_in6 v6;
1245 if (1 == inet_pton (AF_INET6,
1249 v6.sin6_port = htons ((uint16_t) port);
1250 in = GNUNET_memdup (&v6,
1252 *sock_len = sizeof (v6);
1257 /* FIXME (feature!): maybe also try getnameinfo()? */
1264 * Setup cipher for outgoing data stream based on target and
1265 * our ephemeral private key.
1267 * @param queue queue to setup outgoing (encryption) cipher for
1270 setup_out_cipher (struct Queue *queue)
1272 struct GNUNET_HashCode dh;
1274 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral,
1275 &queue->target.public_key,
1277 /* we don't need the private key anymore, drop it! */
1278 memset (&queue->ephemeral,
1280 sizeof (queue->ephemeral));
1286 queue->rekey_time = GNUNET_TIME_relative_to_absolute (REKEY_TIME_INTERVAL);
1287 queue->rekey_left_bytes = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1293 * Inject a `struct TCPRekey` message into the queue's plaintext
1296 * @param queue queue to perform rekeying on
1299 inject_rekey (struct Queue *queue)
1301 struct TCPRekey rekey;
1302 struct TcpHandshakeSignature thp;
1304 GNUNET_assert (0 == queue->pwrite_off);
1308 GNUNET_assert (GNUNET_OK ==
1309 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1310 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1311 rekey.header.size = ntohs (sizeof (rekey));
1312 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1314 rekey.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1315 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
1316 thp.purpose.size = htonl (sizeof (thp));
1317 thp.sender = my_identity;
1318 thp.receiver = queue->target;
1319 thp.ephemeral = rekey.ephemeral;
1320 thp.monotonic_time = rekey.monotonic_time;
1321 GNUNET_assert (GNUNET_OK ==
1322 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1324 &rekey.sender_sig));
1325 hmac (&queue->out_hmac,
1329 memcpy (queue->pwrite_buf,
1332 queue->rekey_state = GNUNET_YES;
1337 * We encrypted the rekey message, now update actually swap the key
1338 * material and update the key freshness parameters of @a queue.
1341 switch_key (struct Queue *queue)
1343 queue->rekey_state = GNUNET_NO;
1344 gcry_cipher_close (queue->out_cipher);
1345 setup_out_cipher (queue);
1350 * We have been notified that our socket is ready to write.
1351 * Then reschedule this function to be called again once more is available.
1353 * @param cls a `struct Queue`
1356 queue_write (void *cls)
1358 struct Queue *queue = cls;
1361 queue->write_task = NULL;
1362 sent = GNUNET_NETWORK_socket_send (queue->sock,
1365 if ( (-1 == sent) &&
1366 (EAGAIN != errno) &&
1369 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1371 queue_destroy (queue);
1376 size_t usent = (size_t) sent;
1378 memmove (queue->cwrite_buf,
1379 &queue->cwrite_buf[usent],
1380 queue->cwrite_off - usent);
1381 reschedule_queue_timeout (queue);
1383 /* can we encrypt more? (always encrypt full messages, needed
1384 such that #mq_cancel() can work!) */
1385 if (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE)
1388 gcry_cipher_encrypt (queue->out_cipher,
1389 &queue->cwrite_buf[queue->cwrite_off],
1392 queue->pwrite_off));
1393 if (queue->rekey_left_bytes > queue->pwrite_off)
1394 queue->rekey_left_bytes -= queue->pwrite_off;
1396 queue->rekey_left_bytes = 0;
1397 queue->cwrite_off += queue->pwrite_off;
1398 queue->pwrite_off = 0;
1400 if ( (GNUNET_YES == queue->rekey_state) &&
1401 (0 == queue->pwrite_off) )
1403 if ( (0 == queue->pwrite_off) &&
1404 ( (0 == queue->rekey_left_bytes) ||
1405 (0 == GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us) ) )
1406 inject_rekey (queue);
1407 if ( (0 == queue->pwrite_off) &&
1408 (! queue->finishing) &&
1409 (queue->mq_awaits_continue) )
1411 queue->mq_awaits_continue = GNUNET_NO;
1412 GNUNET_MQ_impl_send_continue (queue->mq);
1414 /* did we just finish writing 'finish'? */
1415 if ( (0 == queue->cwrite_off) &&
1416 (GNUNET_YES == queue->finishing) )
1418 queue_destroy (queue);
1421 /* do we care to write more? */
1422 if (0 < queue->cwrite_off)
1424 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1432 * Signature of functions implementing the sending functionality of a
1435 * @param mq the message queue
1436 * @param msg the message to send
1437 * @param impl_state our `struct Queue`
1440 mq_send (struct GNUNET_MQ_Handle *mq,
1441 const struct GNUNET_MessageHeader *msg,
1444 struct Queue *queue = impl_state;
1445 uint16_t msize = ntohs (msg->size);
1448 GNUNET_assert (mq == queue->mq);
1449 if (GNUNET_YES == queue->finishing)
1450 return; /* this queue is dying, drop msg */
1451 GNUNET_assert (0 == queue->pread_off);
1452 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
1453 box.header.size = htons (msize);
1454 hmac (&queue->out_hmac,
1458 memcpy (&queue->pread_buf[queue->pread_off],
1461 queue->pread_off += sizeof (box);
1462 memcpy (&queue->pread_buf[queue->pread_off],
1465 queue->pread_off += msize;
1466 GNUNET_assert (NULL != queue->sock);
1467 if (NULL == queue->write_task)
1469 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1477 * Signature of functions implementing the destruction of a message
1478 * queue. Implementations must not free @a mq, but should take care
1481 * @param mq the message queue to destroy
1482 * @param impl_state our `struct Queue`
1485 mq_destroy (struct GNUNET_MQ_Handle *mq,
1488 struct Queue *queue = impl_state;
1490 if (mq == queue->mq)
1493 queue_finish (queue);
1499 * Implementation function that cancels the currently sent message.
1501 * @param mq message queue
1502 * @param impl_state our `struct Queue`
1505 mq_cancel (struct GNUNET_MQ_Handle *mq,
1508 struct Queue *queue = impl_state;
1510 GNUNET_assert (0 != queue->pwrite_off);
1511 queue->pwrite_off = 0;
1516 * Generic error handler, called with the appropriate
1517 * error code and the same closure specified at the creation of
1518 * the message queue.
1519 * Not every message queue implementation supports an error handler.
1521 * @param cls our `struct Queue`
1522 * @param error error code
1525 mq_error (void *cls,
1526 enum GNUNET_MQ_Error error)
1528 struct Queue *queue = cls;
1530 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1531 "MQ error in queue to %s: %d\n",
1532 GNUNET_i2s (&queue->target),
1534 queue_finish (queue);
1539 * Add the given @a queue to our internal data structure. Setup the
1540 * MQ processing and inform transport that the queue is ready. Must
1541 * be called after the KX for outgoing messages has been bootstrapped.
1543 * @param queue queue to boot
1546 boot_queue (struct Queue *queue,
1547 enum GNUNET_TRANSPORT_ConnectionStatus cs)
1549 queue->nt = GNUNET_NT_scanner_get_type (is,
1551 queue->address_len);
1552 (void) GNUNET_CONTAINER_multipeermap_put (queue_map,
1555 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1556 GNUNET_STATISTICS_set (stats,
1558 GNUNET_CONTAINER_multipeermap_size (queue_map),
1561 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1563 = GNUNET_MQ_queue_for_callbacks (&mq_send,
1573 switch (queue->address->sa_family)
1576 GNUNET_asprintf (&foreign_addr,
1578 COMMUNICATOR_ADDRESS_PREFIX,
1583 GNUNET_asprintf (&foreign_addr,
1585 COMMUNICATOR_ADDRESS_PREFIX,
1593 = GNUNET_TRANSPORT_communicator_mq_add (ch,
1600 GNUNET_free (foreign_addr);
1606 * Generate and transmit our ephemeral key and the signature for
1607 * the initial KX with the other peer. Must be called first, before
1608 * any other bytes are ever written to the output buffer. Note that
1609 * our cipher must already be initialized when calling this function.
1610 * Helper function for #start_initial_kx_out().
1612 * @param queue queue to do KX for
1613 * @param epub our public key for the KX
1616 transmit_kx (struct Queue *queue,
1617 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1619 struct TcpHandshakeSignature ths;
1620 struct TCPConfirmation tc;
1622 memcpy (queue->cwrite_buf,
1625 queue->cwrite_off = sizeof (epub);
1626 /* compute 'tc' and append in encrypted format to cwrite_buf */
1627 tc.sender = my_identity;
1628 tc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1629 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1630 ths.purpose.size = htonl (sizeof (ths));
1631 ths.sender = my_identity;
1632 ths.receiver = queue->target;
1633 ths.ephemeral = *epub;
1634 ths.monotonic_time = tc.monotonic_time;
1635 GNUNET_assert (GNUNET_OK ==
1636 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1640 gcry_cipher_encrypt (queue->out_cipher,
1641 &queue->cwrite_buf[queue->cwrite_off],
1645 queue->cwrite_off += sizeof (tc);
1650 * Initialize our key material for outgoing transmissions and
1651 * inform the other peer about it. Must be called first before
1654 * @param queue the queue to setup
1657 start_initial_kx_out (struct Queue *queue)
1659 struct GNUNET_CRYPTO_EcdhePublicKey epub;
1661 GNUNET_assert (GNUNET_OK ==
1662 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1663 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1665 setup_out_cipher (queue);
1672 * We have received the first bytes from the other side on a @a queue.
1673 * Decrypt the @a tc contained in @a ibuf and check the signature.
1674 * Note that #setup_in_cipher() must have already been called.
1676 * @param queue queue to decrypt initial bytes from other peer for
1677 * @param tc[out] where to store the result
1678 * @param ibuf incoming data, of size
1680 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
1683 decrypt_and_check_tc (struct Queue *queue,
1684 struct TCPConfirmation *tc,
1687 struct TcpHandshakeSignature ths;
1690 gcry_cipher_decrypt (queue->in_cipher,
1693 &ibuf[sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)],
1695 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1696 ths.purpose.size = htonl (sizeof (ths));
1697 ths.sender = tc->sender;
1698 ths.receiver = my_identity;
1699 memcpy (&ths.ephemeral,
1701 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1702 ths.monotonic_time = tc->monotonic_time;
1703 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
1706 &tc->sender.public_key);
1711 * Closes socket and frees memory associated with @a pq.
1713 * @param pq proto queue to free
1716 free_proto_queue (struct ProtoQueue *pq)
1718 GNUNET_NETWORK_socket_close (pq->sock);
1719 GNUNET_free (pq->address);
1720 GNUNET_CONTAINER_DLL_remove (proto_head,
1728 * Read from the socket of the proto queue until we have enough data
1729 * to upgrade to full queue.
1731 * @param cls a `struct ProtoQueue`
1734 proto_read_kx (void *cls)
1736 struct ProtoQueue *pq = cls;
1738 struct GNUNET_TIME_Relative left;
1739 struct Queue *queue;
1740 struct TCPConfirmation tc;
1742 pq->read_task = NULL;
1743 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
1744 if (0 == left.rel_value_us)
1746 free_proto_queue (pq);
1749 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
1750 &pq->ibuf[pq->ibuf_off],
1751 sizeof (pq->ibuf) - pq->ibuf_off);
1754 if ( (EAGAIN != errno) &&
1757 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1759 free_proto_queue (pq);
1763 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1769 pq->ibuf_off += rcvd;
1770 if (pq->ibuf_off > sizeof (pq->ibuf))
1773 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1779 /* we got all the data, let's find out who we are talking to! */
1780 queue = GNUNET_new (struct Queue);
1781 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
1784 decrypt_and_check_tc (queue,
1788 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1789 "Invalid TCP KX received from %s\n",
1790 GNUNET_a2s (queue->address,
1791 queue->address_len));
1792 gcry_cipher_close (queue->in_cipher);
1793 GNUNET_free (queue);
1794 free_proto_queue (pq);
1797 queue->address = pq->address; /* steals reference */
1798 queue->address_len = pq->address_len;
1799 queue->target = tc.sender;
1800 start_initial_kx_out (queue);
1802 GNUNET_TRANSPORT_CS_INBOUND);
1804 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1808 GNUNET_CONTAINER_DLL_remove (proto_head,
1816 * We have been notified that our listen socket has something to
1817 * read. Do the read and reschedule this function to be called again
1818 * once more is available.
1823 listen_cb (void *cls)
1825 struct sockaddr_storage in;
1827 struct GNUNET_NETWORK_Handle *sock;
1828 struct ProtoQueue *pq;
1831 GNUNET_assert (NULL != listen_sock);
1832 addrlen = sizeof (in);
1836 sock = GNUNET_NETWORK_socket_accept (listen_sock,
1837 (struct sockaddr *) &in,
1839 if ( (NULL == sock) &&
1840 ( (EMFILE == errno) ||
1841 (ENFILE == errno) ) )
1842 return; /* system limit reached, wait until connection goes down */
1843 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1847 if ( (NULL == sock) &&
1848 ( (EAGAIN == errno) ||
1849 (ENOBUFS == errno) ) )
1853 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1857 pq = GNUNET_new (struct ProtoQueue);
1858 pq->address_len = addrlen;
1859 pq->address = GNUNET_memdup (&in,
1861 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
1863 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
1867 GNUNET_CONTAINER_DLL_insert (proto_head,
1874 * Read from the socket of the queue until we have enough data
1875 * to initialize the decryption logic and can switch to regular
1878 * @param cls a `struct Queue`
1881 queue_read_kx (void *cls)
1883 struct Queue *queue = cls;
1885 struct GNUNET_TIME_Relative left;
1886 struct TCPConfirmation tc;
1888 queue->read_task = NULL;
1889 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1890 if (0 == left.rel_value_us)
1892 queue_destroy (queue);
1895 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1896 &queue->cread_buf[queue->cread_off],
1897 BUF_SIZE - queue->cread_off);
1900 if ( (EAGAIN != errno) &&
1903 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1905 queue_destroy (queue);
1908 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1914 queue->cread_off += rcvd;
1915 if (queue->cread_off <
1919 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1925 /* we got all the data, let's find out who we are talking to! */
1926 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) queue->cread_buf,
1929 decrypt_and_check_tc (queue,
1933 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1934 "Invalid TCP KX received from %s\n",
1935 GNUNET_a2s (queue->address,
1936 queue->address_len));
1937 queue_destroy (queue);
1940 if (0 != memcmp (&tc.sender,
1942 sizeof (struct GNUNET_PeerIdentity)))
1944 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1945 "Invalid sender in TCP KX received from %s\n",
1946 GNUNET_a2s (queue->address,
1947 queue->address_len));
1948 queue_destroy (queue);
1952 /* update queue timeout */
1953 reschedule_queue_timeout (queue);
1954 /* prepare to continue with regular read task immediately */
1955 memmove (queue->cread_buf,
1956 &queue->cread_buf[INITIAL_KX_SIZE],
1957 queue->cread_off - (INITIAL_KX_SIZE));
1958 queue->cread_off -= INITIAL_KX_SIZE;
1959 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read,
1965 * Function called by the transport service to initialize a
1966 * message queue given address information about another peer.
1967 * If and when the communication channel is established, the
1968 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
1969 * to notify the service that the channel is now up. It is
1970 * the responsibility of the communicator to manage sane
1971 * retries and timeouts for any @a peer/@a address combination
1972 * provided by the transport service. Timeouts and retries
1973 * do not need to be signalled to the transport service.
1975 * @param cls closure
1976 * @param peer identity of the other peer
1977 * @param address where to send the message, human-readable
1978 * communicator-specific format, 0-terminated, UTF-8
1979 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
1983 const struct GNUNET_PeerIdentity *peer,
1984 const char *address)
1986 struct Queue *queue;
1988 struct sockaddr *in;
1990 struct GNUNET_NETWORK_Handle *sock;
1992 if (0 != strncmp (address,
1993 COMMUNICATOR_ADDRESS_PREFIX "-",
1994 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1996 GNUNET_break_op (0);
1997 return GNUNET_SYSERR;
1999 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2000 in = tcp_address_to_sockaddr (path,
2003 sock = GNUNET_NETWORK_socket_create (in->sa_family,
2008 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2009 "socket(%d) failed: %s",
2013 return GNUNET_SYSERR;
2016 GNUNET_NETWORK_socket_connect (sock,
2020 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2021 "connect to `%s' failed: %s",
2024 GNUNET_NETWORK_socket_close (sock);
2026 return GNUNET_SYSERR;
2029 queue = GNUNET_new (struct Queue);
2030 queue->target = *peer;
2031 queue->address = in;
2032 queue->address_len = in_len;
2035 GNUNET_TRANSPORT_CS_OUTBOUND);
2037 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2043 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2044 "Failed to setup queue to %s at `%s'\n",
2047 GNUNET_NETWORK_socket_close (sock);
2050 start_initial_kx_out (queue);
2056 * Iterator over all message queues to clean up.
2059 * @param target unused
2060 * @param value the queue to destroy
2061 * @return #GNUNET_OK to continue to iterate
2064 get_queue_delete_it (void *cls,
2065 const struct GNUNET_PeerIdentity *target,
2068 struct Queue *queue = value;
2072 queue_destroy (queue);
2078 * Shutdown the UNIX communicator.
2080 * @param cls NULL (always)
2083 do_shutdown (void *cls)
2087 GNUNET_NAT_unregister (nat);
2090 if (NULL != listen_task)
2092 GNUNET_SCHEDULER_cancel (listen_task);
2095 if (NULL != listen_sock)
2097 GNUNET_break (GNUNET_OK ==
2098 GNUNET_NETWORK_socket_close (listen_sock));
2101 GNUNET_CONTAINER_multipeermap_iterate (queue_map,
2102 &get_queue_delete_it,
2104 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
2107 GNUNET_TRANSPORT_communicator_disconnect (ch);
2112 GNUNET_STATISTICS_destroy (stats,
2116 if (NULL != my_private_key)
2118 GNUNET_free (my_private_key);
2119 my_private_key = NULL;
2123 GNUNET_NT_scanner_done (is);
2130 * Function called when the transport service has received an
2131 * acknowledgement for this communicator (!) via a different return
2134 * Not applicable for TCP.
2136 * @param cls closure
2137 * @param sender which peer sent the notification
2138 * @param msg payload
2141 enc_notify_cb (void *cls,
2142 const struct GNUNET_PeerIdentity *sender,
2143 const struct GNUNET_MessageHeader *msg)
2148 GNUNET_break_op (0);
2153 * Signature of the callback passed to #GNUNET_NAT_register() for
2154 * a function to call whenever our set of 'valid' addresses changes.
2156 * @param cls closure
2157 * @param add_remove #GNUNET_YES to add a new public IP address,
2158 * #GNUNET_NO to remove a previous (now invalid) one
2159 * @param ac address class the address belongs to
2160 * @param addr either the previous or the new public IP address
2161 * @param addrlen actual length of the @a addr
2164 nat_address_cb (void *cls,
2166 enum GNUNET_NAT_AddressClass ac,
2167 const struct sockaddr *addr,
2171 static struct GNUNET_TRANSPORT_AddressIdentifier *ai; // FIXME: store in *ctx of NAT!
2173 if (GNUNET_YES == add_remove)
2175 // FIXME: do better job at stringification of @a addr?
2176 GNUNET_asprintf (&my_addr,
2178 COMMUNICATOR_ADDRESS_PREFIX,
2181 // FIXME: translate 'ac' to 'nt'?
2182 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2184 GNUNET_NT_LOOPBACK, // FIXME: wrong NT!
2185 GNUNET_TIME_UNIT_FOREVER_REL);
2186 GNUNET_free (my_addr);
2190 // FIXME: support removal! => improve NAT API!
2191 GNUNET_TRANSPORT_communicator_address_remove (ai);
2198 * Setup communicator and launch network interactions.
2200 * @param cls NULL (always)
2201 * @param args remaining command-line arguments
2202 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2203 * @param c configuration
2208 const char *cfgfile,
2209 const struct GNUNET_CONFIGURATION_Handle *c)
2212 struct sockaddr *in;
2218 GNUNET_CONFIGURATION_get_value_filename (cfg,
2219 COMMUNICATOR_CONFIG_SECTION,
2223 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2224 COMMUNICATOR_CONFIG_SECTION,
2229 GNUNET_CONFIGURATION_get_value_number (cfg,
2230 COMMUNICATOR_CONFIG_SECTION,
2233 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2235 in = tcp_address_to_sockaddr (bindto,
2239 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2240 "Failed to setup TCP socket address with path `%s'\n",
2242 GNUNET_free (bindto);
2245 listen_sock = GNUNET_NETWORK_socket_create (in->sa_family,
2248 if (NULL == listen_sock)
2250 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2253 GNUNET_free (bindto);
2257 GNUNET_NETWORK_socket_bind (listen_sock,
2261 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2264 GNUNET_NETWORK_socket_close (listen_sock);
2267 GNUNET_free (bindto);
2271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2274 GNUNET_free (bindto);
2275 stats = GNUNET_STATISTICS_create ("C-TCP",
2277 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
2279 is = GNUNET_NT_scanner_init ();
2280 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2281 if (NULL == my_private_key)
2283 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2284 _("Transport service is lacking key configuration settings. Exiting.\n"));
2285 GNUNET_SCHEDULER_shutdown ();
2288 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
2289 &my_identity.public_key);
2290 /* start listening */
2291 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2295 queue_map = GNUNET_CONTAINER_multipeermap_create (10,
2297 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2298 COMMUNICATOR_CONFIG_SECTION,
2299 COMMUNICATOR_ADDRESS_PREFIX,
2300 GNUNET_TRANSPORT_CC_RELIABLE,
2308 GNUNET_SCHEDULER_shutdown ();
2311 nat = GNUNET_NAT_register (cfg,
2312 COMMUNICATOR_CONFIG_SECTION,
2314 1 /* one address */,
2315 (const struct sockaddr **) &in,
2318 NULL /* FIXME: support reversal! */,
2319 NULL /* closure */);
2324 * The main function for the UNIX communicator.
2326 * @param argc number of arguments from the command line
2327 * @param argv command line arguments
2328 * @return 0 ok, 1 on error
2334 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2335 GNUNET_GETOPT_OPTION_END
2340 GNUNET_STRINGS_get_utf8_args (argc, argv,
2346 GNUNET_PROGRAM_run (argc, argv,
2347 "gnunet-communicator-tcp",
2348 _("GNUnet TCP communicator"),
2352 GNUNET_free ((void*) argv);
2357 #if defined(LINUX) && defined(__GLIBC__)
2361 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
2363 void __attribute__ ((constructor))
2364 GNUNET_ARM_memory_init ()
2366 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
2367 mallopt (M_TOP_PAD, 1 * 1024);
2372 /* end of gnunet-communicator-tcp.c */