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 * - handling of rekeys!
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.
430 * Handle for an incoming connection where we do not yet have enough
431 * information to setup a full queue.
439 struct ProtoQueue *next;
444 struct ProtoQueue *prev;
447 * socket that we transmit all data with on this queue
449 struct GNUNET_NETWORK_Handle *sock;
452 * ID of read task for this connection.
454 struct GNUNET_SCHEDULER_Task *read_task;
457 * Address of the other peer.
459 struct sockaddr *address;
462 * Length of the address.
464 socklen_t address_len;
467 * Timeout for this protoqueue.
469 struct GNUNET_TIME_Absolute timeout;
472 * Buffer for reading all the information we need to upgrade from
473 * protoqueue to queue.
475 char ibuf[INITIAL_KX_SIZE];
478 * Current offset for reading into @e ibuf.
487 static struct GNUNET_SCHEDULER_Task *listen_task;
490 * Maximum queue length before we stop reading towards the transport service.
492 static unsigned long long max_queue_length;
495 * For logging statistics.
497 static struct GNUNET_STATISTICS_Handle *stats;
502 static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
505 * Queues (map from peer identity to `struct Queue`)
507 static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
512 static struct GNUNET_NETWORK_Handle *listen_sock;
517 static struct GNUNET_PeerIdentity my_identity;
522 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
527 static const struct GNUNET_CONFIGURATION_Handle *cfg;
530 * Connection to NAT service.
532 static struct GNUNET_NAT_Handle *nat;
535 * Protoqueues DLL head.
537 static struct ProtoQueue *proto_head;
540 * Protoqueues DLL tail.
542 static struct ProtoQueue *proto_tail;
546 * We have been notified that our listen socket has something to
547 * read. Do the read and reschedule this function to be called again
548 * once more is available.
553 listen_cb (void *cls);
557 * Functions with this signature are called whenever we need
558 * to close a queue due to a disconnect or failure to
559 * establish a connection.
561 * @param queue queue to close down
564 queue_destroy (struct Queue *queue)
566 struct GNUNET_MQ_Handle *mq;
568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
569 "Disconnecting queue for peer `%s'\n",
570 GNUNET_i2s (&queue->target));
571 if (NULL != (mq = queue->mq))
574 GNUNET_MQ_destroy (mq);
576 GNUNET_assert (GNUNET_YES ==
577 GNUNET_CONTAINER_multipeermap_remove (queue_map,
580 GNUNET_STATISTICS_set (stats,
582 GNUNET_CONTAINER_multipeermap_size (queue_map),
584 if (NULL != queue->read_task)
586 GNUNET_SCHEDULER_cancel (queue->read_task);
587 queue->read_task = NULL;
589 if (NULL != queue->write_task)
591 GNUNET_SCHEDULER_cancel (queue->write_task);
592 queue->write_task = NULL;
594 GNUNET_NETWORK_socket_close (queue->sock);
595 gcry_cipher_close (queue->in_cipher);
596 gcry_cipher_close (queue->out_cipher);
597 GNUNET_free (queue->address);
598 if (0 != queue->backpressure)
599 queue->destroyed = GNUNET_YES;
602 if (NULL == listen_task)
603 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
611 * Compute @a mac over @a buf, and ratched the @a hmac_secret.
613 * @param[in,out] hmac_secret secret for HMAC calculation
614 * @param buf buffer to MAC
615 * @param buf_size number of bytes in @a buf
616 * @param smac[out] where to write the HMAC
619 hmac (struct GNUNET_HashCode *hmac_secret,
622 struct GNUNET_ShortHashCode *smac)
624 struct GNUNET_HashCode mac;
626 GNUNET_CRYPTO_hmac_raw (hmac_secret,
627 sizeof (struct GNUNET_HashCode),
631 /* truncate to `struct GNUNET_ShortHashCode` */
634 sizeof (struct GNUNET_ShortHashCode));
635 /* ratchet hmac key */
636 GNUNET_CRYPTO_hash (hmac_secret,
637 sizeof (struct GNUNET_HashCode),
643 * Append a 'finish' message to the outgoing transmission. Once the
644 * finish has been transmitted, destroy the queue.
646 * @param queue queue to shut down nicely
649 queue_finish (struct Queue *queue)
651 struct TCPFinish fin;
656 fin.header.size = htons (sizeof (fin));
657 fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
658 hmac (&queue->out_hmac,
662 /* if there is any message left in pwrite_buf, we
663 overwrite it (possibly dropping the last message
664 from CORE hard here) */
665 memcpy (queue->pwrite_buf,
668 queue->pwrite_off = sizeof (fin);
669 /* This flag will ensure that #queue_write() no longer
670 notifies CORE about the possibility of sending
671 more data, and that #queue_write() will call
672 #queue_destroy() once the @c fin was fully written. */
673 queue->finishing = GNUNET_YES;
678 * Increment queue timeout due to activity. We do not immediately
679 * notify the monitor here as that might generate excessive
682 * @param queue queue for which the timeout should be rescheduled
685 reschedule_queue_timeout (struct Queue *queue)
688 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
693 * Queue read task. If we hit the timeout, disconnect it
695 * @param cls the `struct Queue *` to disconnect
698 queue_read (void *cls);
702 * Core tells us it is done processing a message that transport
703 * received on a queue with status @a success.
705 * @param cls a `struct Queue *` where the message originally came from
706 * @param success #GNUNET_OK on success
709 core_read_finished_cb (void *cls,
712 struct Queue *queue = cls;
714 if (GNUNET_OK != success)
715 GNUNET_STATISTICS_update (stats,
716 "# messages lost in communicator API towards CORE",
719 queue->backpressure--;
720 /* handle deferred queue destruction */
721 if ( (queue->destroyed) &&
722 (0 == queue->backpressure) )
727 reschedule_queue_timeout (queue);
728 /* possibly unchoke reading, now that CORE made progress */
729 if (NULL == queue->read_task)
731 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (queue->timeout),
739 * We received @a plaintext_len bytes of @a plaintext on @a queue.
740 * Pass it on to CORE. If transmission is actually happening,
741 * increase backpressure counter.
743 * @param queue the queue that received the plaintext
744 * @param plaintext the plaintext that was received
745 * @param plaintext_len number of bytes of plaintext received
748 pass_plaintext_to_core (struct Queue *queue,
749 const void *plaintext,
750 size_t plaintext_len)
752 const struct GNUNET_MessageHeader *hdr = plaintext;
755 if (ntohs (hdr->size) != plaintext_len)
757 /* NOTE: If we ever allow multiple CORE messages in one
758 BOX, this will have to change! */
762 ret = GNUNET_TRANSPORT_communicator_receive (ch,
765 &core_read_finished_cb,
767 if (GNUNET_OK == ret)
768 queue->backpressure++;
769 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
770 if (GNUNET_SYSERR == ret)
771 GNUNET_STATISTICS_update (stats,
772 "# bytes lost due to CORE not running",
779 * Test if we have received a full message in plaintext.
782 * @param queue queue to process inbound plaintext for
785 try_handle_plaintext (struct Queue *queue)
787 const struct GNUNET_MessageHeader *hdr
788 = (const struct GNUNET_MessageHeader *) queue->pread_buf;
789 const struct TCPBox *box
790 = (const struct TCPBox *) queue->pread_buf;
791 const struct TCPRekey *rekey
792 = (const struct TCPRekey *) queue->pread_buf;
793 const struct TCPFinish *fin
794 = (const struct TCPFinish *) queue->pread_buf;
795 struct TCPRekey rekeyz;
796 struct TCPFinish finz;
797 struct GNUNET_ShortHashCode tmac;
799 size_t size = 0; /* make compiler happy */
801 if (sizeof (*hdr) > queue->pread_off)
802 return; /* not even a header */
803 type = ntohs (hdr->type);
806 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
807 /* Special case: header size excludes box itself! */
808 if (ntohs (hdr->size) + sizeof (struct TCPBox) > queue->pread_off)
810 hmac (&queue->in_hmac,
814 if (0 != memcmp (&tmac,
819 queue_finish (queue);
822 pass_plaintext_to_core (queue,
823 (const void *) &box[1],
825 size = ntohs (hdr->size) + sizeof (*box);
827 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
828 if (sizeof (*rekey) > queue->pread_off)
830 if (ntohs (hdr->size) != sizeof (*rekey))
833 queue_finish (queue);
837 memset (&rekeyz.hmac,
839 sizeof (rekeyz.hmac));
840 hmac (&queue->in_hmac,
844 if (0 != memcmp (&tmac,
849 queue_finish (queue);
852 // FIXME: handle rekey!
854 size = ntohs (hdr->size);
856 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
857 if (sizeof (*fin) > queue->pread_off)
859 if (ntohs (hdr->size) != sizeof (*fin))
862 queue_finish (queue);
869 hmac (&queue->in_hmac,
873 if (0 != memcmp (&tmac,
878 queue_finish (queue);
881 /* handle FINISH by destroying queue */
882 queue_destroy (queue);
886 queue_finish (queue);
889 GNUNET_assert (0 != size);
890 /* 'size' bytes of plaintext were used, shift buffer */
891 GNUNET_assert (size <= queue->pread_off);
892 memmove (queue->pread_buf,
893 &queue->pread_buf[size],
894 queue->pread_off - size);
895 queue->pread_off -= size;
900 * Queue read task. If we hit the timeout, disconnect it
902 * @param cls the `struct Queue *` to disconnect
905 queue_read (void *cls)
907 struct Queue *queue = cls;
908 struct GNUNET_TIME_Relative left;
911 queue->read_task = NULL;
912 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
913 &queue->cread_buf[queue->cread_off],
914 BUF_SIZE - queue->cread_off);
917 if ( (EAGAIN != errno) &&
920 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
922 queue_finish (queue);
927 = GNUNET_SCHEDULER_add_read_net (left,
934 reschedule_queue_timeout (queue);
935 queue->cread_off += rcvd;
936 if (queue->pread_off < sizeof (queue->pread_buf))
938 size_t max = GNUNET_MIN (sizeof (queue->pread_buf) - queue->pread_off,
941 gcry_cipher_decrypt (queue->in_cipher,
942 &queue->pread_buf[queue->pread_off],
946 queue->pread_off += max;
947 memmove (queue->cread_buf,
948 &queue->cread_buf[max],
949 queue->cread_off - max);
950 queue->cread_off -= max;
951 try_handle_plaintext (queue);
954 if (BUF_SIZE == queue->cread_off)
955 return; /* buffer full, suspend reading */
956 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
957 if (0 != left.rel_value_us)
959 if (max_queue_length < queue->backpressure)
961 /* continue reading */
963 = GNUNET_SCHEDULER_add_read_net (left,
970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
971 "Queue %p was idle for %s, disconnecting\n",
973 GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
975 queue_finish (queue);
980 * Convert TCP bind specification to a `struct sockaddr *`
982 * @param bindto bind specification to convert
983 * @param[out] sock_len set to the length of the address
984 * @return converted bindto specification
986 static struct sockaddr *
987 tcp_address_to_sockaddr (const char *bindto,
996 if (1 == SSCANF (bindto,
1001 /* interpreting value as just a PORT number */
1002 if (port > UINT16_MAX)
1004 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1005 "BINDTO specification `%s' invalid: value too large for port\n",
1010 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1011 COMMUNICATOR_CONFIG_SECTION,
1014 struct sockaddr_in *i4;
1016 i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1017 i4->sin_family = AF_INET;
1018 i4->sin_port = htons ((uint16_t) port);
1019 *sock_len = sizeof (struct sockaddr_in);
1020 in = (struct sockaddr *) i4;
1024 struct sockaddr_in6 *i6;
1026 i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1027 i6->sin6_family = AF_INET6;
1028 i6->sin6_port = htons ((uint16_t) port);
1029 *sock_len = sizeof (struct sockaddr_in6);
1030 in = (struct sockaddr *) i6;
1034 cp = GNUNET_strdup (bindto);
1035 colon = strrchr (cp, ':');
1038 /* interpet value after colon as port */
1041 if (1 == SSCANF (colon,
1046 /* interpreting value as just a PORT number */
1047 if (port > UINT16_MAX)
1049 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1050 "BINDTO specification `%s' invalid: value too large for port\n",
1058 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1059 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1067 /* interpret missing port as 0, aka pick any free one */
1072 struct sockaddr_in v4;
1074 if (1 == inet_pton (AF_INET,
1078 v4.sin_port = htons ((uint16_t) port);
1079 in = GNUNET_memdup (&v4,
1081 *sock_len = sizeof (v4);
1088 struct sockaddr_in6 v6;
1090 if (1 == inet_pton (AF_INET6,
1094 v6.sin6_port = htons ((uint16_t) port);
1095 in = GNUNET_memdup (&v6,
1097 *sock_len = sizeof (v6);
1102 /* FIXME (feature!): maybe also try getnameinfo()? */
1109 * Setup @a cipher based on shared secret @a dh and decrypting
1112 * @param dh shared secret
1113 * @param pid decrypting peer's identity
1114 * @param cipher[out] cipher to initialize
1115 * @param hmac_key[out] HMAC key to initialize
1118 setup_cipher (const struct GNUNET_HashCode *dh,
1119 const struct GNUNET_PeerIdentity *pid,
1120 gcry_cipher_hd_t *cipher,
1121 struct GNUNET_HashCode *hmac_key)
1126 gcry_cipher_open (cipher,
1127 GCRY_CIPHER_AES256 /* low level: go for speed */,
1128 GCRY_CIPHER_MODE_CTR,
1130 GNUNET_assert (GNUNET_YES ==
1131 GNUNET_CRYPTO_kdf (key,
1140 gcry_cipher_setkey (*cipher,
1143 GNUNET_assert (GNUNET_YES ==
1144 GNUNET_CRYPTO_kdf (ctr,
1153 gcry_cipher_setctr (*cipher,
1156 GNUNET_assert (GNUNET_YES ==
1157 GNUNET_CRYPTO_kdf (hmac_key,
1158 sizeof (struct GNUNET_HashCode),
1160 strlen ("TCP-hmac"),
1170 * Setup cipher of @a queue for decryption.
1172 * @param ephemeral ephemeral key we received from the other peer
1173 * @param queue[in,out] queue to initialize decryption cipher for
1176 setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1177 struct Queue *queue)
1179 struct GNUNET_HashCode dh;
1181 GNUNET_CRYPTO_eddsa_ecdh (my_private_key,
1192 * Setup cipher for outgoing data stream based on target and
1193 * our ephemeral private key.
1195 * @param queue queue to setup outgoing (encryption) cipher for
1198 setup_out_cipher (struct Queue *queue)
1200 struct GNUNET_HashCode dh;
1202 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral,
1203 &queue->target.public_key,
1205 /* we don't need the private key anymore, drop it! */
1206 memset (&queue->ephemeral,
1208 sizeof (queue->ephemeral));
1214 queue->rekey_time = GNUNET_TIME_relative_to_absolute (REKEY_TIME_INTERVAL);
1215 queue->rekey_left_bytes = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1221 * Inject a `struct TCPRekey` message into the queue's plaintext
1224 * @param queue queue to perform rekeying on
1227 inject_rekey (struct Queue *queue)
1229 struct TCPRekey rekey;
1230 struct TcpHandshakeSignature thp;
1232 GNUNET_assert (0 == queue->pwrite_off);
1236 GNUNET_assert (GNUNET_OK ==
1237 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1238 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1239 rekey.header.size = ntohs (sizeof (rekey));
1240 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1242 rekey.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1243 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY);
1244 thp.purpose.size = htonl (sizeof (thp));
1245 thp.sender = my_identity;
1246 thp.receiver = queue->target;
1247 thp.ephemeral = rekey.ephemeral;
1248 thp.monotonic_time = rekey.monotonic_time;
1249 GNUNET_assert (GNUNET_OK ==
1250 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1252 &rekey.sender_sig));
1253 hmac (&queue->out_hmac,
1257 memcpy (queue->pwrite_buf,
1260 queue->rekey_state = GNUNET_YES;
1265 * We encrypted the rekey message, now update actually swap the key
1266 * material and update the key freshness parameters of @a queue.
1269 switch_key (struct Queue *queue)
1271 queue->rekey_state = GNUNET_NO;
1272 gcry_cipher_close (queue->out_cipher);
1273 setup_out_cipher (queue);
1278 * We have been notified that our socket is ready to write.
1279 * Then reschedule this function to be called again once more is available.
1281 * @param cls a `struct Queue`
1284 queue_write (void *cls)
1286 struct Queue *queue = cls;
1289 queue->write_task = NULL;
1290 sent = GNUNET_NETWORK_socket_send (queue->sock,
1293 if ( (-1 == sent) &&
1294 (EAGAIN != errno) &&
1297 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1299 queue_destroy (queue);
1304 size_t usent = (size_t) sent;
1306 memmove (queue->cwrite_buf,
1307 &queue->cwrite_buf[usent],
1308 queue->cwrite_off - usent);
1309 reschedule_queue_timeout (queue);
1311 /* can we encrypt more? (always encrypt full messages, needed
1312 such that #mq_cancel() can work!) */
1313 if (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE)
1316 gcry_cipher_encrypt (queue->out_cipher,
1317 &queue->cwrite_buf[queue->cwrite_off],
1320 queue->pwrite_off));
1321 if (queue->rekey_left_bytes > queue->pwrite_off)
1322 queue->rekey_left_bytes -= queue->pwrite_off;
1324 queue->rekey_left_bytes = 0;
1325 queue->cwrite_off += queue->pwrite_off;
1326 queue->pwrite_off = 0;
1328 if ( (GNUNET_YES == queue->rekey_state) &&
1329 (0 == queue->pwrite_off) )
1331 if ( (0 == queue->pwrite_off) &&
1332 ( (0 == queue->rekey_left_bytes) ||
1333 (0 == GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us) ) )
1334 inject_rekey (queue);
1335 if ( (0 == queue->pwrite_off) &&
1336 (! queue->finishing) &&
1337 (queue->mq_awaits_continue) )
1339 queue->mq_awaits_continue = GNUNET_NO;
1340 GNUNET_MQ_impl_send_continue (queue->mq);
1342 /* did we just finish writing 'finish'? */
1343 if ( (0 == queue->cwrite_off) &&
1344 (GNUNET_YES == queue->finishing) )
1346 queue_destroy (queue);
1349 /* do we care to write more? */
1350 if (0 < queue->cwrite_off)
1352 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1360 * Signature of functions implementing the sending functionality of a
1363 * @param mq the message queue
1364 * @param msg the message to send
1365 * @param impl_state our `struct Queue`
1368 mq_send (struct GNUNET_MQ_Handle *mq,
1369 const struct GNUNET_MessageHeader *msg,
1372 struct Queue *queue = impl_state;
1373 uint16_t msize = ntohs (msg->size);
1376 GNUNET_assert (mq == queue->mq);
1377 if (GNUNET_YES == queue->finishing)
1378 return; /* this queue is dying, drop msg */
1379 GNUNET_assert (0 == queue->pread_off);
1380 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
1381 box.header.size = htons (msize);
1382 hmac (&queue->out_hmac,
1386 memcpy (&queue->pread_buf[queue->pread_off],
1389 queue->pread_off += sizeof (box);
1390 memcpy (&queue->pread_buf[queue->pread_off],
1393 queue->pread_off += msize;
1394 GNUNET_assert (NULL != queue->sock);
1395 if (NULL == queue->write_task)
1397 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1405 * Signature of functions implementing the destruction of a message
1406 * queue. Implementations must not free @a mq, but should take care
1409 * @param mq the message queue to destroy
1410 * @param impl_state our `struct Queue`
1413 mq_destroy (struct GNUNET_MQ_Handle *mq,
1416 struct Queue *queue = impl_state;
1418 if (mq == queue->mq)
1421 queue_finish (queue);
1427 * Implementation function that cancels the currently sent message.
1429 * @param mq message queue
1430 * @param impl_state our `struct Queue`
1433 mq_cancel (struct GNUNET_MQ_Handle *mq,
1436 struct Queue *queue = impl_state;
1438 GNUNET_assert (0 != queue->pwrite_off);
1439 queue->pwrite_off = 0;
1444 * Generic error handler, called with the appropriate
1445 * error code and the same closure specified at the creation of
1446 * the message queue.
1447 * Not every message queue implementation supports an error handler.
1449 * @param cls our `struct Queue`
1450 * @param error error code
1453 mq_error (void *cls,
1454 enum GNUNET_MQ_Error error)
1456 struct Queue *queue = cls;
1458 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1459 "MQ error in queue to %s: %d\n",
1460 GNUNET_i2s (&queue->target),
1462 queue_finish (queue);
1467 * Add the given @a queue to our internal data structure. Setup the
1468 * MQ processing and inform transport that the queue is ready. Must
1469 * be called after the KX for outgoing messages has been bootstrapped.
1471 * @param queue queue to boot
1474 boot_queue (struct Queue *queue,
1475 enum GNUNET_TRANSPORT_ConnectionStatus cs)
1477 queue->nt = 0; // FIXME: determine NT!
1478 (void) GNUNET_CONTAINER_multipeermap_put (queue_map,
1481 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1482 GNUNET_STATISTICS_set (stats,
1484 GNUNET_CONTAINER_multipeermap_size (queue_map),
1487 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1489 = GNUNET_MQ_queue_for_callbacks (&mq_send,
1499 switch (queue->address->sa_family)
1502 GNUNET_asprintf (&foreign_addr,
1504 COMMUNICATOR_ADDRESS_PREFIX,
1509 GNUNET_asprintf (&foreign_addr,
1511 COMMUNICATOR_ADDRESS_PREFIX,
1519 = GNUNET_TRANSPORT_communicator_mq_add (ch,
1526 GNUNET_free (foreign_addr);
1532 * Generate and transmit our ephemeral key and the signature for
1533 * the initial KX with the other peer. Must be called first, before
1534 * any other bytes are ever written to the output buffer. Note that
1535 * our cipher must already be initialized when calling this function.
1536 * Helper function for #start_initial_kx_out().
1538 * @param queue queue to do KX for
1539 * @param epub our public key for the KX
1542 transmit_kx (struct Queue *queue,
1543 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1545 struct TcpHandshakeSignature ths;
1546 struct TCPConfirmation tc;
1548 memcpy (queue->cwrite_buf,
1551 queue->cwrite_off = sizeof (epub);
1552 /* compute 'tc' and append in encrypted format to cwrite_buf */
1553 tc.sender = my_identity;
1554 tc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1555 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1556 ths.purpose.size = htonl (sizeof (ths));
1557 ths.sender = my_identity;
1558 ths.receiver = queue->target;
1559 ths.ephemeral = *epub;
1560 ths.monotonic_time = tc.monotonic_time;
1561 GNUNET_assert (GNUNET_OK ==
1562 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1566 gcry_cipher_encrypt (queue->out_cipher,
1567 &queue->cwrite_buf[queue->cwrite_off],
1571 queue->cwrite_off += sizeof (tc);
1576 * Initialize our key material for outgoing transmissions and
1577 * inform the other peer about it. Must be called first before
1580 * @param queue the queue to setup
1583 start_initial_kx_out (struct Queue *queue)
1585 struct GNUNET_CRYPTO_EcdhePublicKey epub;
1587 GNUNET_assert (GNUNET_OK ==
1588 GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral));
1589 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1591 setup_out_cipher (queue);
1598 * We have received the first bytes from the other side on a @a queue.
1599 * Decrypt the @a tc contained in @a ibuf and check the signature.
1600 * Note that #setup_in_cipher() must have already been called.
1602 * @param queue queue to decrypt initial bytes from other peer for
1603 * @param tc[out] where to store the result
1604 * @param ibuf incoming data, of size
1606 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
1609 decrypt_and_check_tc (struct Queue *queue,
1610 struct TCPConfirmation *tc,
1613 struct TcpHandshakeSignature ths;
1616 gcry_cipher_decrypt (queue->in_cipher,
1619 &ibuf[sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)],
1621 ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
1622 ths.purpose.size = htonl (sizeof (ths));
1623 ths.sender = tc->sender;
1624 ths.receiver = my_identity;
1625 memcpy (&ths.ephemeral,
1627 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1628 ths.monotonic_time = tc->monotonic_time;
1629 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
1632 &tc->sender.public_key);
1637 * Closes socket and frees memory associated with @a pq.
1639 * @param pq proto queue to free
1642 free_proto_queue (struct ProtoQueue *pq)
1644 GNUNET_NETWORK_socket_close (pq->sock);
1645 GNUNET_free (pq->address);
1646 GNUNET_CONTAINER_DLL_remove (proto_head,
1654 * Read from the socket of the proto queue until we have enough data
1655 * to upgrade to full queue.
1657 * @param cls a `struct ProtoQueue`
1660 proto_read_kx (void *cls)
1662 struct ProtoQueue *pq = cls;
1664 struct GNUNET_TIME_Relative left;
1665 struct Queue *queue;
1666 struct TCPConfirmation tc;
1668 pq->read_task = NULL;
1669 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
1670 if (0 == left.rel_value_us)
1672 free_proto_queue (pq);
1675 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
1676 &pq->ibuf[pq->ibuf_off],
1677 sizeof (pq->ibuf) - pq->ibuf_off);
1680 if ( (EAGAIN != errno) &&
1683 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1685 free_proto_queue (pq);
1689 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1695 pq->ibuf_off += rcvd;
1696 if (pq->ibuf_off > sizeof (pq->ibuf))
1699 pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1705 /* we got all the data, let's find out who we are talking to! */
1706 queue = GNUNET_new (struct Queue);
1707 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
1710 decrypt_and_check_tc (queue,
1714 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1715 "Invalid TCP KX received from %s\n",
1716 GNUNET_a2s (queue->address,
1717 queue->address_len));
1718 gcry_cipher_close (queue->in_cipher);
1719 GNUNET_free (queue);
1720 free_proto_queue (pq);
1723 queue->address = pq->address; /* steals reference */
1724 queue->address_len = pq->address_len;
1725 queue->target = tc.sender;
1726 start_initial_kx_out (queue);
1728 GNUNET_TRANSPORT_CS_INBOUND);
1730 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1734 GNUNET_CONTAINER_DLL_remove (proto_head,
1742 * We have been notified that our listen socket has something to
1743 * read. Do the read and reschedule this function to be called again
1744 * once more is available.
1749 listen_cb (void *cls)
1751 struct sockaddr_storage in;
1753 struct GNUNET_NETWORK_Handle *sock;
1754 struct ProtoQueue *pq;
1757 GNUNET_assert (NULL != listen_sock);
1758 addrlen = sizeof (in);
1762 sock = GNUNET_NETWORK_socket_accept (listen_sock,
1763 (struct sockaddr *) &in,
1765 if ( (NULL == sock) &&
1766 ( (EMFILE == errno) ||
1767 (ENFILE == errno) ) )
1768 return; /* system limit reached, wait until connection goes down */
1769 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1773 if ( (NULL == sock) &&
1774 ( (EAGAIN == errno) ||
1775 (ENOBUFS == errno) ) )
1779 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1783 pq = GNUNET_new (struct ProtoQueue);
1784 pq->address_len = addrlen;
1785 pq->address = GNUNET_memdup (&in,
1787 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
1789 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
1793 GNUNET_CONTAINER_DLL_insert (proto_head,
1800 * Read from the socket of the queue until we have enough data
1801 * to initialize the decryption logic and can switch to regular
1804 * @param cls a `struct Queue`
1807 queue_read_kx (void *cls)
1809 struct Queue *queue = cls;
1811 struct GNUNET_TIME_Relative left;
1812 struct TCPConfirmation tc;
1814 queue->read_task = NULL;
1815 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1816 if (0 == left.rel_value_us)
1818 queue_destroy (queue);
1821 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1822 &queue->cread_buf[queue->cread_off],
1823 BUF_SIZE - queue->cread_off);
1826 if ( (EAGAIN != errno) &&
1829 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1831 queue_destroy (queue);
1834 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1840 queue->cread_off += rcvd;
1841 if (queue->cread_off <
1845 queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1851 /* we got all the data, let's find out who we are talking to! */
1852 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) queue->cread_buf,
1855 decrypt_and_check_tc (queue,
1859 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1860 "Invalid TCP KX received from %s\n",
1861 GNUNET_a2s (queue->address,
1862 queue->address_len));
1863 queue_destroy (queue);
1866 if (0 != memcmp (&tc.sender,
1868 sizeof (struct GNUNET_PeerIdentity)))
1870 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1871 "Invalid sender in TCP KX received from %s\n",
1872 GNUNET_a2s (queue->address,
1873 queue->address_len));
1874 queue_destroy (queue);
1878 /* update queue timeout */
1879 reschedule_queue_timeout (queue);
1880 /* prepare to continue with regular read task immediately */
1881 memmove (queue->cread_buf,
1882 &queue->cread_buf[INITIAL_KX_SIZE],
1883 queue->cread_off - (INITIAL_KX_SIZE));
1884 queue->cread_off -= INITIAL_KX_SIZE;
1885 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read,
1891 * Function called by the transport service to initialize a
1892 * message queue given address information about another peer.
1893 * If and when the communication channel is established, the
1894 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
1895 * to notify the service that the channel is now up. It is
1896 * the responsibility of the communicator to manage sane
1897 * retries and timeouts for any @a peer/@a address combination
1898 * provided by the transport service. Timeouts and retries
1899 * do not need to be signalled to the transport service.
1901 * @param cls closure
1902 * @param peer identity of the other peer
1903 * @param address where to send the message, human-readable
1904 * communicator-specific format, 0-terminated, UTF-8
1905 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
1909 const struct GNUNET_PeerIdentity *peer,
1910 const char *address)
1912 struct Queue *queue;
1914 struct sockaddr *in;
1916 struct GNUNET_NETWORK_Handle *sock;
1918 if (0 != strncmp (address,
1919 COMMUNICATOR_ADDRESS_PREFIX "-",
1920 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1922 GNUNET_break_op (0);
1923 return GNUNET_SYSERR;
1925 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1926 in = tcp_address_to_sockaddr (path,
1929 sock = GNUNET_NETWORK_socket_create (in->sa_family,
1934 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1935 "socket(%d) failed: %s",
1939 return GNUNET_SYSERR;
1942 GNUNET_NETWORK_socket_connect (sock,
1946 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1947 "connect to `%s' failed: %s",
1950 GNUNET_NETWORK_socket_close (sock);
1952 return GNUNET_SYSERR;
1955 queue = GNUNET_new (struct Queue);
1956 queue->target = *peer;
1957 queue->address = in;
1958 queue->address_len = in_len;
1961 GNUNET_TRANSPORT_CS_OUTBOUND);
1963 = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1969 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1970 "Failed to setup queue to %s at `%s'\n",
1973 GNUNET_NETWORK_socket_close (sock);
1976 start_initial_kx_out (queue);
1982 * Iterator over all message queues to clean up.
1985 * @param target unused
1986 * @param value the queue to destroy
1987 * @return #GNUNET_OK to continue to iterate
1990 get_queue_delete_it (void *cls,
1991 const struct GNUNET_PeerIdentity *target,
1994 struct Queue *queue = value;
1998 queue_destroy (queue);
2004 * Shutdown the UNIX communicator.
2006 * @param cls NULL (always)
2009 do_shutdown (void *cls)
2013 GNUNET_NAT_unregister (nat);
2016 if (NULL != listen_task)
2018 GNUNET_SCHEDULER_cancel (listen_task);
2021 if (NULL != listen_sock)
2023 GNUNET_break (GNUNET_OK ==
2024 GNUNET_NETWORK_socket_close (listen_sock));
2027 GNUNET_CONTAINER_multipeermap_iterate (queue_map,
2028 &get_queue_delete_it,
2030 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
2033 GNUNET_TRANSPORT_communicator_disconnect (ch);
2038 GNUNET_STATISTICS_destroy (stats,
2042 if (NULL != my_private_key)
2044 GNUNET_free (my_private_key);
2045 my_private_key = NULL;
2051 * Function called when the transport service has received an
2052 * acknowledgement for this communicator (!) via a different return
2055 * Not applicable for TCP.
2057 * @param cls closure
2058 * @param sender which peer sent the notification
2059 * @param msg payload
2062 enc_notify_cb (void *cls,
2063 const struct GNUNET_PeerIdentity *sender,
2064 const struct GNUNET_MessageHeader *msg)
2069 GNUNET_break_op (0);
2074 * Signature of the callback passed to #GNUNET_NAT_register() for
2075 * a function to call whenever our set of 'valid' addresses changes.
2077 * @param cls closure
2078 * @param add_remove #GNUNET_YES to add a new public IP address,
2079 * #GNUNET_NO to remove a previous (now invalid) one
2080 * @param ac address class the address belongs to
2081 * @param addr either the previous or the new public IP address
2082 * @param addrlen actual length of the @a addr
2085 nat_address_cb (void *cls,
2087 enum GNUNET_NAT_AddressClass ac,
2088 const struct sockaddr *addr,
2092 static struct GNUNET_TRANSPORT_AddressIdentifier *ai; // FIXME: store in *ctx of NAT!
2094 if (GNUNET_YES == add_remove)
2096 // FIXME: do better job at stringification of @a addr?
2097 GNUNET_asprintf (&my_addr,
2099 COMMUNICATOR_ADDRESS_PREFIX,
2102 // FIXME: translate 'ac' to 'nt'?
2103 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2105 GNUNET_NT_LOOPBACK, // FIXME: wrong NT!
2106 GNUNET_TIME_UNIT_FOREVER_REL);
2107 GNUNET_free (my_addr);
2111 // FIXME: support removal! => improve NAT API!
2112 GNUNET_TRANSPORT_communicator_address_remove (ai);
2119 * Setup communicator and launch network interactions.
2121 * @param cls NULL (always)
2122 * @param args remaining command-line arguments
2123 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2124 * @param c configuration
2129 const char *cfgfile,
2130 const struct GNUNET_CONFIGURATION_Handle *c)
2133 struct sockaddr *in;
2139 GNUNET_CONFIGURATION_get_value_filename (cfg,
2140 COMMUNICATOR_CONFIG_SECTION,
2144 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2145 COMMUNICATOR_CONFIG_SECTION,
2150 GNUNET_CONFIGURATION_get_value_number (cfg,
2151 COMMUNICATOR_CONFIG_SECTION,
2154 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2156 in = tcp_address_to_sockaddr (bindto,
2160 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2161 "Failed to setup TCP socket address with path `%s'\n",
2163 GNUNET_free (bindto);
2166 listen_sock = GNUNET_NETWORK_socket_create (in->sa_family,
2169 if (NULL == listen_sock)
2171 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2174 GNUNET_free (bindto);
2178 GNUNET_NETWORK_socket_bind (listen_sock,
2182 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2185 GNUNET_NETWORK_socket_close (listen_sock);
2188 GNUNET_free (bindto);
2192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2195 GNUNET_free (bindto);
2196 stats = GNUNET_STATISTICS_create ("C-TCP",
2198 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
2200 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2201 if (NULL == my_private_key)
2203 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2204 _("Transport service is lacking key configuration settings. Exiting.\n"));
2205 GNUNET_SCHEDULER_shutdown ();
2208 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
2209 &my_identity.public_key);
2210 /* start listening */
2211 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2215 queue_map = GNUNET_CONTAINER_multipeermap_create (10,
2217 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2218 COMMUNICATOR_CONFIG_SECTION,
2219 COMMUNICATOR_ADDRESS_PREFIX,
2220 GNUNET_TRANSPORT_CC_RELIABLE,
2228 GNUNET_SCHEDULER_shutdown ();
2231 nat = GNUNET_NAT_register (cfg,
2232 COMMUNICATOR_CONFIG_SECTION,
2234 1 /* one address */,
2235 (const struct sockaddr **) &in,
2238 NULL /* FIXME: support reversal! */,
2239 NULL /* closure */);
2244 * The main function for the UNIX communicator.
2246 * @param argc number of arguments from the command line
2247 * @param argv command line arguments
2248 * @return 0 ok, 1 on error
2254 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2255 GNUNET_GETOPT_OPTION_END
2260 GNUNET_STRINGS_get_utf8_args (argc, argv,
2266 GNUNET_PROGRAM_run (argc, argv,
2267 "gnunet-communicator-tcp",
2268 _("GNUnet TCP communicator"),
2272 GNUNET_free ((void*) argv);
2277 #if defined(LINUX) && defined(__GLIBC__)
2281 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
2283 void __attribute__ ((constructor))
2284 GNUNET_ARM_memory_init ()
2286 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
2287 mallopt (M_TOP_PAD, 1 * 1024);
2292 /* end of gnunet-communicator-tcp.c */