more work on TCP communicator, almost there
[oweals/gnunet.git] / src / transport / gnunet-communicator-tcp.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2010-2014, 2018, 2019 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21 /**
22  * @file transport/gnunet-communicator-tcp.c
23  * @brief Transport plugin using TCP.
24  * @author Christian Grothoff
25  *
26  * TODO:
27  * - NAT service API change to handle address stops!
28  * - handling of rekeys!
29  */
30 #include "platform.h"
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"
39
40 /**
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.
47  */
48 #define DEFAULT_MAX_QUEUE_LENGTH 8
49
50 /**
51  * Size of our IO buffers for ciphertext data. Must be at
52  * least UINT_MAX + sizeof (struct TCPBox).
53  */
54 #define BUF_SIZE (2 * 64 * 1024 + sizeof (struct TCPBox))
55
56 /**
57  * How often do we rekey based on time (at least)
58  */ 
59 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
60
61 /**
62  * How long do we wait until we must have received the initial KX?
63  */ 
64 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
65
66 /**
67  * How often do we rekey based on number of bytes transmitted?
68  * (additionally randomized).
69  */ 
70 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
71
72 /**
73  * Size of the initial key exchange message sent first in both
74  * directions.
75  */
76 #define INITIAL_KX_SIZE (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof (struct TCPConfirmation))
77
78
79 /**
80  * Address prefix used by the communicator.
81  */
82 #define COMMUNICATOR_ADDRESS_PREFIX "tcp"
83
84 /**
85  * Configuration section used by the communicator.
86  */
87 #define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
88
89 GNUNET_NETWORK_STRUCT_BEGIN
90
91
92 /**
93  * Signature we use to verify that the ephemeral key was really chosen by
94  * the specified sender.
95  */
96 struct TcpHandshakeSignature
97 {
98   /**
99    * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
100    */
101   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
102
103   /**
104    * Identity of the inititor of the TCP connection (TCP client).
105    */ 
106   struct GNUNET_PeerIdentity sender;
107
108   /**
109    * Presumed identity of the target of the TCP connection (TCP server)
110    */ 
111   struct GNUNET_PeerIdentity receiver;
112
113   /**
114    * Ephemeral key used by the @e sender.
115    */ 
116   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
117
118   /**
119    * Monotonic time of @e sender, to possibly help detect replay attacks
120    * (if receiver persists times by sender).
121    */ 
122   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
123 };
124
125
126 /**
127  * Encrypted continuation of TCP initial handshake.
128  */
129 struct TCPConfirmation
130 {
131   /**
132    * Sender's identity
133    */
134   struct GNUNET_PeerIdentity sender;
135
136   /**
137    * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
138    */
139   struct GNUNET_CRYPTO_EddsaSignature sender_sig;
140
141   /**
142    * Monotonic time of @e sender, to possibly help detect replay attacks
143    * (if receiver persists times by sender).
144    */ 
145   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
146
147 };
148
149
150 /**
151  * TCP message box.  Always sent encrypted!
152  */ 
153 struct TCPBox
154 {
155   
156   /**
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)!!
161    */ 
162   struct GNUNET_MessageHeader header;
163
164   /**
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.
171    */ 
172   struct GNUNET_ShortHashCode hmac;
173
174   /* followed by as may bytes of payload as indicated in @e header,
175      excluding the TCPBox itself! */
176   
177 };
178
179
180 /**
181  * TCP rekey message box.  Always sent encrypted!  Data after
182  * this message will use the new key.
183  */ 
184 struct TCPRekey
185 {
186
187   /**
188    * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
189    */ 
190   struct GNUNET_MessageHeader header;
191
192   /**
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.
199    */ 
200   struct GNUNET_ShortHashCode hmac;
201
202   /**
203    * New ephemeral key.
204    */ 
205   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
206   
207   /**
208    * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY
209    */
210   struct GNUNET_CRYPTO_EddsaSignature sender_sig;
211
212   /**
213    * Monotonic time of @e sender, to possibly help detect replay attacks
214    * (if receiver persists times by sender).
215    */ 
216   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
217
218 };
219
220
221 /**
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.
225  */ 
226 struct TCPFinish
227 {
228
229   /**
230    * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
231    */ 
232   struct GNUNET_MessageHeader header;
233
234   /**
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.
241    */ 
242   struct GNUNET_ShortHashCode hmac;
243
244 };
245
246
247 GNUNET_NETWORK_STRUCT_END
248
249
250 /**
251  * Handle for a queue.
252  */
253 struct Queue
254 {
255
256   /**
257    * To whom are we talking to.
258    */
259   struct GNUNET_PeerIdentity target;
260
261   /**
262    * socket that we transmit all data with on this queue
263    */
264   struct GNUNET_NETWORK_Handle *sock;
265
266   /**
267    * cipher for decryption of incoming data.
268    */ 
269   gcry_cipher_hd_t in_cipher;
270
271   /**
272    * cipher for encryption of outgoing data.
273    */
274   gcry_cipher_hd_t out_cipher;
275
276   /**
277    * Shared secret for HMAC verification on incoming data.
278    */ 
279   struct GNUNET_HashCode in_hmac;
280
281   /**
282    * Shared secret for HMAC generation on outgoing data, ratcheted after
283    * each operation.
284    */ 
285   struct GNUNET_HashCode out_hmac;
286
287   /**
288    * Our ephemeral key. Stored here temporarily during rekeying / key generation.
289    */
290   struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral;
291   
292   /**
293    * ID of read task for this connection.
294    */
295   struct GNUNET_SCHEDULER_Task *read_task;
296
297   /**
298    * ID of write task for this connection.
299    */
300   struct GNUNET_SCHEDULER_Task *write_task;
301
302   /**
303    * Address of the other peer.
304    */
305   struct sockaddr *address;
306   
307   /**
308    * How many more bytes may we sent with the current @e out_cipher
309    * before we should rekey?
310    */
311   uint64_t rekey_left_bytes;
312
313   /**
314    * Until what time may we sent with the current @e out_cipher
315    * before we should rekey?
316    */
317   struct GNUNET_TIME_Absolute rekey_time;
318   
319   /**
320    * Length of the address.
321    */
322   socklen_t address_len;
323
324   /**
325    * Message queue we are providing for the #ch.
326    */
327   struct GNUNET_MQ_Handle *mq;
328
329   /**
330    * handle for this queue with the #ch.
331    */
332   struct GNUNET_TRANSPORT_QueueHandle *qh;
333
334   /**
335    * Number of bytes we currently have in our write queue.
336    */
337   unsigned long long bytes_in_queue;
338
339   /**
340    * Buffer for reading ciphertext from network into.
341    */
342   char cread_buf[BUF_SIZE];
343
344   /**
345    * buffer for writing ciphertext to network.
346    */
347   char cwrite_buf[BUF_SIZE];
348
349   /**
350    * Plaintext buffer for decrypted plaintext.
351    */
352   char pread_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
353
354   /**
355    * Plaintext buffer for messages to be encrypted.
356    */
357   char pwrite_buf[UINT16_MAX + 1 + sizeof (struct TCPBox)];
358   
359   /**
360    * At which offset in the ciphertext read buffer should we
361    * append more ciphertext for transmission next?
362    */
363   size_t cread_off;
364
365   /**
366    * At which offset in the ciphertext write buffer should we
367    * append more ciphertext from reading next?
368    */
369   size_t cwrite_off;
370   
371   /**
372    * At which offset in the plaintext input buffer should we
373    * append more plaintext from decryption next?
374    */
375   size_t pread_off;
376   
377   /**
378    * At which offset in the plaintext output buffer should we
379    * append more plaintext for encryption next?
380    */
381   size_t pwrite_off;
382
383   /**
384    * Timeout for this queue.
385    */
386   struct GNUNET_TIME_Absolute timeout;
387
388   /**
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.
394    */ 
395   unsigned int backpressure;
396   
397   /**
398    * Which network type does this queue use?
399    */
400   enum GNUNET_NetworkType nt;
401   
402   /**
403    * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call?
404    */
405   int mq_awaits_continue;
406   
407   /**
408    * Did we enqueue a finish message and are closing down the queue?
409    */
410   int finishing;
411
412   /**
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.
417    */
418   int destroyed;
419
420   /**
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.
424    */
425   int rekey_state;
426 };
427
428
429 /**
430  * Handle for an incoming connection where we do not yet have enough
431  * information to setup a full queue.
432  */
433 struct ProtoQueue
434 {
435
436   /**
437    * Kept in a DLL.
438    */ 
439   struct ProtoQueue *next;
440
441   /**
442    * Kept in a DLL.
443    */ 
444   struct ProtoQueue *prev;
445   
446   /**
447    * socket that we transmit all data with on this queue
448    */
449   struct GNUNET_NETWORK_Handle *sock;
450
451   /**
452    * ID of read task for this connection.
453    */
454   struct GNUNET_SCHEDULER_Task *read_task;
455
456   /**
457    * Address of the other peer.
458    */
459   struct sockaddr *address;
460
461   /**
462    * Length of the address.
463    */
464   socklen_t address_len;
465
466   /**
467    * Timeout for this protoqueue.
468    */
469   struct GNUNET_TIME_Absolute timeout;
470
471   /** 
472    * Buffer for reading all the information we need to upgrade from 
473    * protoqueue to queue.
474    */
475   char ibuf[INITIAL_KX_SIZE];
476
477   /**
478    * Current offset for reading into @e ibuf.
479    */ 
480   size_t ibuf_off;
481 };
482
483
484 /**
485  * ID of listen task
486  */
487 static struct GNUNET_SCHEDULER_Task *listen_task;
488
489 /**
490  * Maximum queue length before we stop reading towards the transport service.
491  */
492 static unsigned long long max_queue_length;
493
494 /**
495  * For logging statistics.
496  */
497 static struct GNUNET_STATISTICS_Handle *stats;
498
499 /**
500  * Our environment.
501  */
502 static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
503
504 /**
505  * Queues (map from peer identity to `struct Queue`)
506  */
507 static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
508
509 /**
510  * Listen socket.
511  */
512 static struct GNUNET_NETWORK_Handle *listen_sock;
513
514 /**
515  * Our public key.
516  */
517 static struct GNUNET_PeerIdentity my_identity;
518
519 /**
520  * Our private key.
521  */
522 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
523
524 /**
525  * Our configuration.
526  */
527 static const struct GNUNET_CONFIGURATION_Handle *cfg;
528
529 /**
530  * Connection to NAT service.
531  */
532 static struct GNUNET_NAT_Handle *nat;
533
534 /**
535  * Protoqueues DLL head.
536  */ 
537 static struct ProtoQueue *proto_head;
538
539 /**
540  * Protoqueues DLL tail.
541  */ 
542 static struct ProtoQueue *proto_tail;
543
544
545 /**
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.
549  *
550  * @param cls NULL
551  */
552 static void
553 listen_cb (void *cls);
554
555
556 /**
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.
560  *
561  * @param queue queue to close down
562  */
563 static void
564 queue_destroy (struct Queue *queue)
565 {
566   struct GNUNET_MQ_Handle *mq;
567
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))
572   {
573     queue->mq = NULL;
574     GNUNET_MQ_destroy (mq);
575   }
576   GNUNET_assert (GNUNET_YES ==
577                  GNUNET_CONTAINER_multipeermap_remove (queue_map,
578                                                        &queue->target,
579                                                        queue));
580   GNUNET_STATISTICS_set (stats,
581                          "# queues active",
582                          GNUNET_CONTAINER_multipeermap_size (queue_map),
583                          GNUNET_NO);
584   if (NULL != queue->read_task)
585   {
586     GNUNET_SCHEDULER_cancel (queue->read_task);
587     queue->read_task = NULL;
588   }
589   if (NULL != queue->write_task)
590   {
591     GNUNET_SCHEDULER_cancel (queue->write_task);
592     queue->write_task = NULL;
593   }
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;
600   else
601     GNUNET_free (queue);
602   if (NULL == listen_task)
603     listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
604                                                  listen_sock,
605                                                  &listen_cb,
606                                                  NULL);
607 }
608
609
610 /**
611  * Compute @a mac over @a buf, and ratched the @a hmac_secret.
612  *
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
617  */
618 static void
619 hmac (struct GNUNET_HashCode *hmac_secret,
620       const void *buf,
621       size_t buf_size,
622       struct GNUNET_ShortHashCode *smac)
623 {
624   struct GNUNET_HashCode mac;
625
626   GNUNET_CRYPTO_hmac_raw (hmac_secret,
627                           sizeof (struct GNUNET_HashCode),
628                           buf,
629                           buf_size,
630                           &mac);
631   /* truncate to `struct GNUNET_ShortHashCode` */
632   memcpy (smac,
633           &mac,
634           sizeof (struct GNUNET_ShortHashCode));
635   /* ratchet hmac key */
636   GNUNET_CRYPTO_hash (hmac_secret,
637                       sizeof (struct GNUNET_HashCode),
638                       hmac_secret);
639 }
640
641
642 /**
643  * Append a 'finish' message to the outgoing transmission. Once the
644  * finish has been transmitted, destroy the queue.
645  *
646  * @param queue queue to shut down nicely
647  */
648 static void
649 queue_finish (struct Queue *queue)
650 {
651   struct TCPFinish fin;
652
653   memset (&fin,
654           0,
655           sizeof (fin));
656   fin.header.size = htons (sizeof (fin));
657   fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
658   hmac (&queue->out_hmac,
659         &fin,
660         sizeof (fin),
661         &fin.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,
666           &fin,
667           sizeof (fin));
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;
674 }
675
676
677 /**
678  * Increment queue timeout due to activity.  We do not immediately
679  * notify the monitor here as that might generate excessive
680  * signalling.
681  *
682  * @param queue queue for which the timeout should be rescheduled
683  */
684 static void
685 reschedule_queue_timeout (struct Queue *queue)
686 {
687   queue->timeout
688     = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
689 }
690
691
692 /**
693  * Queue read task. If we hit the timeout, disconnect it
694  *
695  * @param cls the `struct Queue *` to disconnect
696  */
697 static void
698 queue_read (void *cls);
699
700
701 /**
702  * Core tells us it is done processing a message that transport
703  * received on a queue with status @a success.
704  *
705  * @param cls a `struct Queue *` where the message originally came from
706  * @param success #GNUNET_OK on success
707  */
708 static void
709 core_read_finished_cb (void *cls,
710                        int success)
711 {
712   struct Queue *queue = cls;
713
714   if (GNUNET_OK != success)
715     GNUNET_STATISTICS_update (stats,
716                               "# messages lost in communicator API towards CORE",
717                               1,
718                               GNUNET_NO);
719   queue->backpressure--;
720   /* handle deferred queue destruction */
721   if ( (queue->destroyed) &&
722        (0 == queue->backpressure) )
723   {
724     GNUNET_free (queue);
725     return;
726   }
727   reschedule_queue_timeout (queue);
728   /* possibly unchoke reading, now that CORE made progress */
729   if (NULL == queue->read_task)
730     queue->read_task
731       = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (queue->timeout),
732                                        queue->sock,
733                                        &queue_read,
734                                        queue);
735 }
736
737
738 /**
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.
742  *
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
746  */ 
747 static void
748 pass_plaintext_to_core (struct Queue *queue,
749                         const void *plaintext,
750                         size_t plaintext_len)
751 {
752   const struct GNUNET_MessageHeader *hdr = plaintext;
753   int ret;
754
755   if (ntohs (hdr->size) != plaintext_len)
756   {
757     /* NOTE: If we ever allow multiple CORE messages in one
758        BOX, this will have to change! */
759     GNUNET_break (0);
760     return;
761   }
762   ret = GNUNET_TRANSPORT_communicator_receive (ch,
763                                                &queue->target,
764                                                hdr,
765                                                &core_read_finished_cb,
766                                                queue);
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",
773                               plaintext_len,
774                               GNUNET_NO);
775 }
776
777
778 /**
779  * Test if we have received a full message in plaintext.
780  * If so, handle it.
781  *
782  * @param queue queue to process inbound plaintext for
783  */ 
784 static void
785 try_handle_plaintext (struct Queue *queue)
786 {
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;
798   uint16_t type;
799   size_t size = 0; /* make compiler happy */
800
801   if (sizeof (*hdr) > queue->pread_off)
802     return; /* not even a header */
803   type = ntohs (hdr->type);
804   switch (type)
805   {
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)
809       return;
810     hmac (&queue->in_hmac,
811           &box[1],
812           ntohs (hdr->size),
813           &tmac);
814     if (0 != memcmp (&tmac,
815                      &box->hmac,
816                      sizeof (tmac)))
817     {
818       GNUNET_break_op (0);
819       queue_finish (queue);
820       return;
821     }
822     pass_plaintext_to_core (queue,
823                             (const void *) &box[1],
824                             ntohs (hdr->size));
825     size = ntohs (hdr->size) + sizeof (*box);
826     break;
827   case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
828     if (sizeof (*rekey) > queue->pread_off)
829       return;
830     if (ntohs (hdr->size) != sizeof (*rekey))
831     {
832       GNUNET_break_op (0);
833       queue_finish (queue);
834       return;
835     }
836     rekeyz = *rekey;
837     memset (&rekeyz.hmac,
838             0,
839             sizeof (rekeyz.hmac));
840     hmac (&queue->in_hmac,
841           &rekeyz,
842           sizeof (rekeyz),
843           &tmac);
844     if (0 != memcmp (&tmac,
845                      &box->hmac,
846                      sizeof (tmac)))
847     {
848       GNUNET_break_op (0);
849       queue_finish (queue);
850       return;
851     }
852     // FIXME: handle rekey!
853
854     size = ntohs (hdr->size);
855     break;
856   case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
857     if (sizeof (*fin) > queue->pread_off)
858       return;
859     if (ntohs (hdr->size) != sizeof (*fin))
860     {
861       GNUNET_break_op (0);
862       queue_finish (queue);
863       return;
864     }
865     finz = *fin;
866     memset (&finz.hmac,
867             0,
868             sizeof (finz.hmac));
869     hmac (&queue->in_hmac,
870           &rekeyz,
871           sizeof (rekeyz),
872           &tmac);
873     if (0 != memcmp (&tmac,
874                      &fin->hmac,
875                      sizeof (tmac)))
876     {
877       GNUNET_break_op (0);
878       queue_finish (queue);
879       return;
880     }
881     /* handle FINISH by destroying queue */
882     queue_destroy (queue);
883     break;
884   default:
885     GNUNET_break_op (0);
886     queue_finish (queue);
887     return;
888   }
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;
896 }
897
898
899 /**
900  * Queue read task. If we hit the timeout, disconnect it
901  *
902  * @param cls the `struct Queue *` to disconnect
903  */
904 static void
905 queue_read (void *cls)
906 {
907   struct Queue *queue = cls;
908   struct GNUNET_TIME_Relative left;
909   ssize_t rcvd;
910
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);
915   if (-1 == rcvd)
916   {
917     if ( (EAGAIN != errno) &&
918          (EINTR != errno) )
919     {
920       GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
921                            "recv");
922       queue_finish (queue);
923       return;
924     }
925     /* try again */
926     queue->read_task
927       = GNUNET_SCHEDULER_add_read_net (left,
928                                        queue->sock,
929                                        &queue_read,
930                                        queue);
931     return;
932   }
933   if (0 != rcvd)
934     reschedule_queue_timeout (queue);
935   queue->cread_off += rcvd;
936   if (queue->pread_off < sizeof (queue->pread_buf))
937   {
938     size_t max = GNUNET_MIN (sizeof (queue->pread_buf) - queue->pread_off,
939                              queue->cread_off);
940     GNUNET_assert (0 ==
941                    gcry_cipher_decrypt (queue->in_cipher,
942                                         &queue->pread_buf[queue->pread_off],
943                                         max,
944                                         queue->cread_buf,
945                                         max));
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);
952   }
953   
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) 
958   {
959     if (max_queue_length < queue->backpressure)
960     {
961       /* continue reading */
962       queue->read_task
963         = GNUNET_SCHEDULER_add_read_net (left,
964                                          queue->sock,
965                                          &queue_read,
966                                          queue);
967     }
968     return;
969   }
970   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
971               "Queue %p was idle for %s, disconnecting\n",
972               queue,
973               GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
974                                                       GNUNET_YES));
975   queue_finish (queue);
976 }
977
978
979 /**
980  * Convert TCP bind specification to a `struct sockaddr *`
981  *
982  * @param bindto bind specification to convert
983  * @param[out] sock_len set to the length of the address
984  * @return converted bindto specification
985  */
986 static struct sockaddr *
987 tcp_address_to_sockaddr (const char *bindto,
988                          socklen_t *sock_len)
989 {
990   struct sockaddr *in;
991   unsigned int port;
992   char dummy[2];
993   char *colon;
994   char *cp;
995   
996   if (1 == SSCANF (bindto,
997                    "%u%1s",
998                    &port,
999                    dummy))
1000   {
1001     /* interpreting value as just a PORT number */
1002     if (port > UINT16_MAX)
1003     {
1004       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1005                   "BINDTO specification `%s' invalid: value too large for port\n",
1006                   bindto);
1007       return NULL;
1008     }
1009     if (GNUNET_YES ==
1010         GNUNET_CONFIGURATION_get_value_yesno (cfg,
1011                                               COMMUNICATOR_CONFIG_SECTION,
1012                                               "DISABLE_V6"))
1013     {
1014       struct sockaddr_in *i4;
1015       
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;
1021     }
1022     else
1023     {
1024       struct sockaddr_in6 *i6;
1025       
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;
1031     }
1032     return in;
1033   }
1034   cp = GNUNET_strdup (bindto);
1035   colon = strrchr (cp, ':');
1036   if (NULL != colon)
1037   {
1038     /* interpet value after colon as port */
1039     *colon = '\0';
1040     colon++;
1041     if (1 == SSCANF (colon,
1042                      "%u%1s",
1043                      &port,
1044                      dummy))
1045     {
1046       /* interpreting value as just a PORT number */
1047       if (port > UINT16_MAX)
1048       {
1049         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1050                     "BINDTO specification `%s' invalid: value too large for port\n",
1051                     bindto);
1052         GNUNET_free (cp);
1053         return NULL;
1054       }
1055     }
1056     else
1057     {
1058       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1059                   "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1060                   bindto);
1061       GNUNET_free (cp);
1062       return NULL;
1063     }
1064   }
1065   else
1066   {
1067     /* interpret missing port as 0, aka pick any free one */
1068     port = 0;
1069   }
1070   {
1071     /* try IPv4 */
1072     struct sockaddr_in v4;
1073
1074     if (1 == inet_pton (AF_INET,
1075                         cp,
1076                         &v4))
1077     {
1078       v4.sin_port = htons ((uint16_t) port);
1079       in = GNUNET_memdup (&v4,
1080                           sizeof (v4));
1081       *sock_len = sizeof (v4);
1082       GNUNET_free (cp);
1083       return in;
1084     }
1085   }
1086   {
1087     /* try IPv6 */
1088     struct sockaddr_in6 v6;
1089
1090     if (1 == inet_pton (AF_INET6,
1091                         cp,
1092                         &v6))
1093     {
1094       v6.sin6_port = htons ((uint16_t) port);
1095       in = GNUNET_memdup (&v6,
1096                           sizeof (v6));
1097       *sock_len = sizeof (v6);
1098       GNUNET_free (cp);
1099       return in;
1100     }
1101   }
1102   /* FIXME (feature!): maybe also try getnameinfo()? */
1103   GNUNET_free (cp);
1104   return NULL;
1105 }
1106
1107
1108 /**
1109  * Setup @a cipher based on shared secret @a dh and decrypting
1110  * peer @a pid.
1111  *
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
1116  */
1117 static void
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)
1122 {
1123   char key[256/8];
1124   char ctr[128/8];
1125
1126   gcry_cipher_open (cipher,
1127                     GCRY_CIPHER_AES256 /* low level: go for speed */,
1128                     GCRY_CIPHER_MODE_CTR,
1129                     0 /* flags */);
1130   GNUNET_assert (GNUNET_YES ==
1131                  GNUNET_CRYPTO_kdf (key,
1132                                     sizeof (key),
1133                                     "TCP-key",
1134                                     strlen ("TCP-key"),
1135                                     dh,
1136                                     sizeof (*dh),
1137                                     pid,
1138                                     sizeof (*pid),
1139                                     NULL, 0));
1140   gcry_cipher_setkey (*cipher,
1141                       key,
1142                       sizeof (key));
1143   GNUNET_assert (GNUNET_YES ==
1144                  GNUNET_CRYPTO_kdf (ctr,
1145                                     sizeof (ctr),
1146                                     "TCP-ctr",
1147                                     strlen ("TCP-ctr"),
1148                                     dh,
1149                                     sizeof (*dh),
1150                                     pid,
1151                                     sizeof (*pid),
1152                                     NULL, 0));
1153   gcry_cipher_setctr (*cipher,
1154                       ctr,
1155                       sizeof (ctr));
1156   GNUNET_assert (GNUNET_YES ==
1157                  GNUNET_CRYPTO_kdf (hmac_key,
1158                                     sizeof (struct GNUNET_HashCode),
1159                                     "TCP-hmac",
1160                                     strlen ("TCP-hmac"),
1161                                     dh,
1162                                     sizeof (*dh),
1163                                     pid,
1164                                     sizeof (*pid),
1165                                     NULL, 0));
1166 }
1167
1168
1169 /**
1170  * Setup cipher of @a queue for decryption.
1171  *
1172  * @param ephemeral ephemeral key we received from the other peer
1173  * @param queue[in,out] queue to initialize decryption cipher for
1174  */
1175 static void
1176 setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1177                  struct Queue *queue)
1178 {
1179   struct GNUNET_HashCode dh;
1180   
1181   GNUNET_CRYPTO_eddsa_ecdh (my_private_key,
1182                             ephemeral,
1183                             &dh);
1184   setup_cipher (&dh,
1185                 &my_identity,
1186                 &queue->in_cipher,
1187                 &queue->in_hmac);
1188 }
1189                 
1190
1191 /**
1192  * Setup cipher for outgoing data stream based on target and
1193  * our ephemeral private key.
1194  *
1195  * @param queue queue to setup outgoing (encryption) cipher for
1196  */
1197 static void
1198 setup_out_cipher (struct Queue *queue)
1199 {
1200   struct GNUNET_HashCode dh;
1201   
1202   GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral,
1203                             &queue->target.public_key,
1204                             &dh);
1205   /* we don't need the private key anymore, drop it! */
1206   memset (&queue->ephemeral,
1207           0,
1208           sizeof (queue->ephemeral));
1209   setup_cipher (&dh,
1210                 &queue->target,
1211                 &queue->out_cipher,
1212                 &queue->out_hmac);
1213   
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,
1216                                                       REKEY_MAX_BYTES);
1217 }
1218
1219
1220 /**
1221  * Inject a `struct TCPRekey` message into the queue's plaintext
1222  * buffer.
1223  *
1224  * @param queue queue to perform rekeying on
1225  */ 
1226 static void
1227 inject_rekey (struct Queue *queue)
1228 {
1229   struct TCPRekey rekey;
1230   struct TcpHandshakeSignature thp;
1231   
1232   GNUNET_assert (0 == queue->pwrite_off);
1233   memset (&rekey,
1234           0,
1235           sizeof (rekey));
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,
1241                                       &rekey.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,
1251                                            &thp.purpose,
1252                                            &rekey.sender_sig));
1253   hmac (&queue->out_hmac,
1254         &rekey,
1255         sizeof (rekey),
1256         &rekey.hmac);
1257   memcpy (queue->pwrite_buf,
1258           &rekey,
1259           sizeof (rekey));
1260   queue->rekey_state = GNUNET_YES;
1261 }
1262
1263
1264 /**
1265  * We encrypted the rekey message, now update actually swap the key
1266  * material and update the key freshness parameters of @a queue.
1267  */ 
1268 static void
1269 switch_key (struct Queue *queue)
1270 {
1271   queue->rekey_state = GNUNET_NO; 
1272   gcry_cipher_close (queue->out_cipher);
1273   setup_out_cipher (queue);
1274 }
1275
1276
1277 /**
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.
1280  *
1281  * @param cls a `struct Queue`
1282  */
1283 static void
1284 queue_write (void *cls)
1285 {
1286   struct Queue *queue = cls;
1287   ssize_t sent;
1288
1289   queue->write_task = NULL;
1290   sent = GNUNET_NETWORK_socket_send (queue->sock,
1291                                      queue->cwrite_buf,
1292                                      queue->cwrite_off);
1293   if ( (-1 == sent) &&
1294        (EAGAIN != errno) &&
1295        (EINTR != errno) )
1296   {
1297     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1298                          "send");
1299     queue_destroy (queue);
1300     return;                      
1301   }
1302   if (sent > 0)
1303   {
1304     size_t usent = (size_t) sent;
1305
1306     memmove (queue->cwrite_buf,
1307              &queue->cwrite_buf[usent],
1308              queue->cwrite_off - usent);
1309     reschedule_queue_timeout (queue);
1310  }
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)
1314   {
1315     GNUNET_assert (0 ==
1316                    gcry_cipher_encrypt (queue->out_cipher,
1317                                         &queue->cwrite_buf[queue->cwrite_off],
1318                                         queue->pwrite_off,
1319                                         queue->pwrite_buf,
1320                                         queue->pwrite_off));
1321     if (queue->rekey_left_bytes > queue->pwrite_off)
1322       queue->rekey_left_bytes -= queue->pwrite_off;
1323     else
1324       queue->rekey_left_bytes = 0;
1325     queue->cwrite_off += queue->pwrite_off;
1326     queue->pwrite_off = 0;
1327   }
1328   if ( (GNUNET_YES == queue->rekey_state) &&
1329        (0 == queue->pwrite_off) )
1330     switch_key (queue);
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) )
1338   {
1339     queue->mq_awaits_continue = GNUNET_NO;
1340     GNUNET_MQ_impl_send_continue (queue->mq);
1341   }
1342   /* did we just finish writing 'finish'? */
1343   if ( (0 == queue->cwrite_off) &&
1344        (GNUNET_YES == queue->finishing) )
1345   {
1346     queue_destroy (queue);
1347     return;
1348   }
1349   /* do we care to write more? */
1350   if (0 < queue->cwrite_off)
1351     queue->write_task 
1352       = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1353                                         queue->sock,
1354                                         &queue_write,
1355                                         queue);
1356 }
1357
1358
1359 /**
1360  * Signature of functions implementing the sending functionality of a
1361  * message queue.
1362  *
1363  * @param mq the message queue
1364  * @param msg the message to send
1365  * @param impl_state our `struct Queue`
1366  */
1367 static void
1368 mq_send (struct GNUNET_MQ_Handle *mq,
1369          const struct GNUNET_MessageHeader *msg,
1370          void *impl_state)
1371 {
1372   struct Queue *queue = impl_state;
1373   uint16_t msize = ntohs (msg->size);
1374   struct TCPBox box;
1375
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,
1383         msg,
1384         msize,
1385         &box.hmac);
1386   memcpy (&queue->pread_buf[queue->pread_off],
1387           &box,
1388           sizeof (box));
1389   queue->pread_off += sizeof (box);
1390   memcpy (&queue->pread_buf[queue->pread_off],
1391           msg,
1392           msize);
1393   queue->pread_off += msize;
1394   GNUNET_assert (NULL != queue->sock);
1395   if (NULL == queue->write_task)
1396     queue->write_task =
1397       GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1398                                       queue->sock,
1399                                       &queue_write,
1400                                       queue);
1401 }
1402
1403
1404 /**
1405  * Signature of functions implementing the destruction of a message
1406  * queue.  Implementations must not free @a mq, but should take care
1407  * of @a impl_state.
1408  *
1409  * @param mq the message queue to destroy
1410  * @param impl_state our `struct Queue`
1411  */
1412 static void
1413 mq_destroy (struct GNUNET_MQ_Handle *mq,
1414             void *impl_state)
1415 {
1416   struct Queue *queue = impl_state;
1417
1418   if (mq == queue->mq)
1419   {
1420     queue->mq = NULL;
1421     queue_finish (queue);
1422   }
1423 }
1424
1425
1426 /**
1427  * Implementation function that cancels the currently sent message.
1428  *
1429  * @param mq message queue
1430  * @param impl_state our `struct Queue`
1431  */
1432 static void
1433 mq_cancel (struct GNUNET_MQ_Handle *mq,
1434            void *impl_state)
1435 {
1436   struct Queue *queue = impl_state;
1437
1438   GNUNET_assert (0 != queue->pwrite_off);
1439   queue->pwrite_off = 0;
1440 }
1441
1442
1443 /**
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.
1448  *
1449  * @param cls our `struct Queue`
1450  * @param error error code
1451  */
1452 static void
1453 mq_error (void *cls,
1454           enum GNUNET_MQ_Error error)
1455 {
1456   struct Queue *queue = cls;
1457
1458   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1459               "MQ error in queue to %s: %d\n",
1460               GNUNET_i2s (&queue->target),
1461               (int) error);
1462   queue_finish (queue);
1463 }
1464
1465
1466 /**
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.
1470  *
1471  * @param queue queue to boot
1472  */ 
1473 static void
1474 boot_queue (struct Queue *queue,
1475             enum GNUNET_TRANSPORT_ConnectionStatus cs)
1476 {
1477   queue->nt = 0; // FIXME: determine NT!
1478   (void) GNUNET_CONTAINER_multipeermap_put (queue_map,
1479                                             &queue->target,
1480                                             queue,
1481                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1482   GNUNET_STATISTICS_set (stats,
1483                          "# queues active",
1484                          GNUNET_CONTAINER_multipeermap_size (queue_map),
1485                          GNUNET_NO);
1486   queue->timeout
1487     = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1488   queue->mq
1489     = GNUNET_MQ_queue_for_callbacks (&mq_send,
1490                                      &mq_destroy,
1491                                      &mq_cancel,
1492                                      queue,
1493                                      NULL,
1494                                      &mq_error,
1495                                      queue);
1496   {
1497     char *foreign_addr;
1498
1499     switch (queue->address->sa_family)
1500     {
1501     case AF_INET:
1502       GNUNET_asprintf (&foreign_addr,
1503                        "%s-%s:%d",
1504                        COMMUNICATOR_ADDRESS_PREFIX,
1505                        "inet-ntop-fixme",
1506                        4242);
1507       break;
1508     case AF_INET6:
1509       GNUNET_asprintf (&foreign_addr,
1510                        "%s-%s:%d",
1511                        COMMUNICATOR_ADDRESS_PREFIX,
1512                        "inet-ntop-fixme",
1513                        4242);
1514       break;
1515     default:
1516       GNUNET_assert (0);
1517     }
1518     queue->qh
1519       = GNUNET_TRANSPORT_communicator_mq_add (ch,
1520                                               &queue->target,
1521                                               foreign_addr,
1522                                               0 /* no MTU */,
1523                                               queue->nt,
1524                                               cs,
1525                                               queue->mq);
1526     GNUNET_free (foreign_addr);
1527   }
1528 }
1529
1530
1531 /**
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().
1537  *
1538  * @param queue queue to do KX for
1539  * @param epub our public key for the KX
1540  */
1541 static void
1542 transmit_kx (struct Queue *queue,
1543              const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1544 {
1545   struct TcpHandshakeSignature ths;
1546   struct TCPConfirmation tc;
1547
1548   memcpy (queue->cwrite_buf,
1549           epub,
1550           sizeof (*epub));
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,
1563                                            &ths.purpose,
1564                                            &tc.sender_sig));
1565   GNUNET_assert (0 ==
1566                  gcry_cipher_encrypt (queue->out_cipher,
1567                                       &queue->cwrite_buf[queue->cwrite_off],
1568                                       sizeof (tc),
1569                                       &tc,
1570                                       sizeof (tc)));
1571   queue->cwrite_off += sizeof (tc);
1572 }
1573
1574
1575 /**
1576  * Initialize our key material for outgoing transmissions and 
1577  * inform the other peer about it. Must be called first before
1578  * any data is sent.
1579  *
1580  * @param queue the queue to setup
1581  */
1582 static void
1583 start_initial_kx_out (struct Queue *queue)
1584 {
1585   struct GNUNET_CRYPTO_EcdhePublicKey epub;
1586
1587   GNUNET_assert (GNUNET_OK ==
1588                  GNUNET_CRYPTO_ecdhe_key_create2 (&queue->ephemeral)); 
1589   GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral,
1590                                       &epub);
1591   setup_out_cipher (queue);
1592   transmit_kx (queue,
1593                &epub);
1594 }
1595
1596
1597 /**
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.
1601  *
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 
1605  *        `INITIAL_KX_SIZE`
1606  * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
1607  */
1608 static int
1609 decrypt_and_check_tc (struct Queue *queue,
1610                       struct TCPConfirmation *tc,
1611                       char *ibuf)
1612 {
1613   struct TcpHandshakeSignature ths;
1614                         
1615   GNUNET_assert (0 ==
1616                  gcry_cipher_decrypt (queue->in_cipher,
1617                                       tc,
1618                                       sizeof (*tc),
1619                                       &ibuf[sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)],
1620                                       sizeof (tc)));
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,
1626           ibuf,
1627           sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1628   ths.monotonic_time = tc->monotonic_time;
1629   return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
1630                                      &ths.purpose,
1631                                      &tc->sender_sig,
1632                                      &tc->sender.public_key);
1633 }
1634
1635
1636 /**
1637  * Closes socket and frees memory associated with @a pq.
1638  *
1639  * @param pq proto queue to free
1640  */ 
1641 static void
1642 free_proto_queue (struct ProtoQueue *pq)
1643 {
1644   GNUNET_NETWORK_socket_close (pq->sock);
1645   GNUNET_free (pq->address);
1646   GNUNET_CONTAINER_DLL_remove (proto_head,
1647                                proto_tail,
1648                                pq);
1649   GNUNET_free (pq);
1650 }
1651  
1652
1653 /**
1654  * Read from the socket of the proto queue until we have enough data
1655  * to upgrade to full queue.
1656  *
1657  * @param cls a `struct ProtoQueue`
1658  */
1659 static void
1660 proto_read_kx (void *cls)
1661 {
1662   struct ProtoQueue *pq = cls;
1663   ssize_t rcvd;
1664   struct GNUNET_TIME_Relative left;
1665   struct Queue *queue;
1666   struct TCPConfirmation tc;
1667   
1668   pq->read_task = NULL;
1669   left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
1670   if (0 == left.rel_value_us)
1671   {
1672     free_proto_queue (pq);
1673     return;
1674   }
1675   rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
1676                                      &pq->ibuf[pq->ibuf_off],
1677                                      sizeof (pq->ibuf) - pq->ibuf_off);
1678   if (-1 == rcvd)
1679   {
1680     if ( (EAGAIN != errno) &&
1681          (EINTR != errno) )
1682     {
1683       GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1684                            "recv");
1685       free_proto_queue (pq);
1686       return;
1687     }
1688     /* try again */
1689     pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1690                                                    pq->sock,
1691                                                    &proto_read_kx,
1692                                                    pq);
1693     return;    
1694   }
1695   pq->ibuf_off += rcvd;
1696   if (pq->ibuf_off > sizeof (pq->ibuf))
1697   {
1698     /* read more */
1699     pq->read_task = GNUNET_SCHEDULER_add_read_net (left,
1700                                                    pq->sock,
1701                                                    &proto_read_kx,
1702                                                    pq);
1703     return;
1704   }
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,
1708                    queue);
1709   if (GNUNET_OK !=
1710       decrypt_and_check_tc (queue,
1711                             &tc,
1712                             pq->ibuf))
1713   {
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);
1721     return;    
1722   }
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);
1727   boot_queue (queue,
1728               GNUNET_TRANSPORT_CS_INBOUND);
1729   queue->read_task
1730     = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1731                                      queue->sock,
1732                                      &queue_read,
1733                                      queue);
1734   GNUNET_CONTAINER_DLL_remove (proto_head,
1735                                proto_tail,
1736                                pq);
1737   GNUNET_free (pq);
1738 }
1739
1740
1741 /**
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.
1745  *
1746  * @param cls NULL
1747  */
1748 static void
1749 listen_cb (void *cls)
1750 {
1751   struct sockaddr_storage in;
1752   socklen_t addrlen;
1753   struct GNUNET_NETWORK_Handle *sock;
1754   struct ProtoQueue *pq;
1755
1756   listen_task = NULL;
1757   GNUNET_assert (NULL != listen_sock);
1758   addrlen = sizeof (in);
1759   memset (&in,
1760           0,
1761           sizeof (in));
1762   sock = GNUNET_NETWORK_socket_accept (listen_sock,
1763                                        (struct sockaddr *) &in,
1764                                        &addrlen);
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,
1770                                                listen_sock,
1771                                                &listen_cb,
1772                                                NULL);
1773   if ( (NULL == sock) &&
1774        ( (EAGAIN == errno) ||
1775          (ENOBUFS == errno) ) )
1776     return;
1777   if (NULL == sock)
1778   {
1779     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1780                          "accept");
1781     return;
1782   }
1783   pq = GNUNET_new (struct ProtoQueue);
1784   pq->address_len = addrlen;
1785   pq->address = GNUNET_memdup (&in,
1786                                addrlen);
1787   pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
1788   pq->sock = sock;
1789   pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
1790                                                  pq->sock,
1791                                                  &proto_read_kx,
1792                                                  pq);
1793   GNUNET_CONTAINER_DLL_insert (proto_head,
1794                                proto_tail,
1795                                pq);
1796 }
1797
1798
1799 /**
1800  * Read from the socket of the queue until we have enough data
1801  * to initialize the decryption logic and can switch to regular
1802  * reading.
1803  *
1804  * @param cls a `struct Queue`
1805  */
1806 static void
1807 queue_read_kx (void *cls)
1808 {
1809   struct Queue *queue = cls;
1810   ssize_t rcvd;
1811   struct GNUNET_TIME_Relative left;
1812   struct TCPConfirmation tc;
1813   
1814   queue->read_task = NULL;
1815   left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1816   if (0 == left.rel_value_us)
1817   {
1818     queue_destroy (queue);
1819     return;
1820   }
1821   rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1822                                      &queue->cread_buf[queue->cread_off],
1823                                      BUF_SIZE - queue->cread_off);
1824   if (-1 == rcvd)
1825   {
1826     if ( (EAGAIN != errno) &&
1827          (EINTR != errno) )
1828     {
1829       GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1830                            "recv");
1831       queue_destroy (queue);
1832       return;
1833     }
1834     queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1835                                                       queue->sock,
1836                                                       &queue_read_kx,
1837                                                       queue);
1838     return;
1839   }
1840   queue->cread_off += rcvd;
1841   if (queue->cread_off <
1842       INITIAL_KX_SIZE)
1843   {
1844     /* read more */
1845     queue->read_task = GNUNET_SCHEDULER_add_read_net (left,
1846                                                       queue->sock,
1847                                                       &queue_read_kx,
1848                                                       queue);
1849     return;
1850   }
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,
1853                    queue);
1854   if (GNUNET_OK !=
1855       decrypt_and_check_tc (queue,
1856                             &tc,
1857                             queue->cread_buf))
1858   {
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);
1864     return;
1865   }
1866   if (0 != memcmp (&tc.sender,
1867                    &queue->target,
1868                    sizeof (struct GNUNET_PeerIdentity)))
1869   {
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);
1875     return;
1876   }
1877
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,
1886                                                queue);
1887 }
1888                                       
1889
1890 /**
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.
1900  *
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
1906  */
1907 static int
1908 mq_init (void *cls,
1909          const struct GNUNET_PeerIdentity *peer,
1910          const char *address)
1911 {
1912   struct Queue *queue;
1913   const char *path;
1914   struct sockaddr *in;
1915   socklen_t in_len;
1916   struct GNUNET_NETWORK_Handle *sock;
1917   
1918   if (0 != strncmp (address,
1919                     COMMUNICATOR_ADDRESS_PREFIX "-",
1920                     strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1921   {
1922     GNUNET_break_op (0);
1923     return GNUNET_SYSERR;
1924   }
1925   path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1926   in = tcp_address_to_sockaddr (path,
1927                                 &in_len);
1928   
1929   sock = GNUNET_NETWORK_socket_create (in->sa_family,
1930                                        SOCK_STREAM,
1931                                        IPPROTO_TCP);
1932   if (NULL == sock)
1933   {
1934     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1935                 "socket(%d) failed: %s",
1936                 in->sa_family,
1937                 STRERROR (errno));
1938     GNUNET_free (in);
1939     return GNUNET_SYSERR;
1940   }
1941   if (GNUNET_OK !=
1942       GNUNET_NETWORK_socket_connect (sock,
1943                                      in,
1944                                      in_len))
1945   {
1946     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1947                 "connect to `%s' failed: %s",
1948                 address,
1949                 STRERROR (errno));
1950     GNUNET_NETWORK_socket_close (sock);
1951     GNUNET_free (in);
1952     return GNUNET_SYSERR;
1953   }
1954
1955   queue = GNUNET_new (struct Queue);
1956   queue->target = *peer; 
1957   queue->address = in;
1958   queue->address_len = in_len;
1959   queue->sock = sock;
1960   boot_queue (queue,
1961               GNUNET_TRANSPORT_CS_OUTBOUND);
1962   queue->read_task
1963     = GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1964                                      queue->sock,
1965                                      &queue_read_kx,
1966                                      queue);
1967   if (NULL == queue)
1968   {
1969     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1970                 "Failed to setup queue to %s at `%s'\n",
1971                 GNUNET_i2s (peer),
1972                 path);
1973     GNUNET_NETWORK_socket_close (sock);
1974     return GNUNET_NO;
1975   }
1976   start_initial_kx_out (queue);
1977   return GNUNET_OK;  
1978 }
1979
1980
1981 /**
1982  * Iterator over all message queues to clean up.
1983  *
1984  * @param cls NULL
1985  * @param target unused
1986  * @param value the queue to destroy
1987  * @return #GNUNET_OK to continue to iterate
1988  */
1989 static int
1990 get_queue_delete_it (void *cls,
1991                      const struct GNUNET_PeerIdentity *target,
1992                      void *value)
1993 {
1994   struct Queue *queue = value;
1995
1996   (void) cls;
1997   (void) target;
1998   queue_destroy (queue);
1999   return GNUNET_OK;
2000 }
2001
2002
2003 /**
2004  * Shutdown the UNIX communicator.
2005  *
2006  * @param cls NULL (always)
2007  */
2008 static void
2009 do_shutdown (void *cls)
2010 {
2011   if (NULL != nat)
2012   {
2013      GNUNET_NAT_unregister (nat);
2014      nat = NULL;
2015   }
2016   if (NULL != listen_task)
2017   {
2018     GNUNET_SCHEDULER_cancel (listen_task);
2019     listen_task = NULL;
2020   }
2021   if (NULL != listen_sock)
2022   {
2023     GNUNET_break (GNUNET_OK ==
2024                   GNUNET_NETWORK_socket_close (listen_sock));
2025     listen_sock = NULL;
2026   }
2027   GNUNET_CONTAINER_multipeermap_iterate (queue_map,
2028                                          &get_queue_delete_it,
2029                                          NULL);
2030   GNUNET_CONTAINER_multipeermap_destroy (queue_map);
2031   if (NULL != ch)
2032   {
2033     GNUNET_TRANSPORT_communicator_disconnect (ch);
2034     ch = NULL;
2035   }
2036   if (NULL != stats)
2037   {
2038     GNUNET_STATISTICS_destroy (stats,
2039                                GNUNET_NO);
2040     stats = NULL;
2041   }
2042   if (NULL != my_private_key)
2043   {
2044     GNUNET_free (my_private_key);
2045     my_private_key = NULL;
2046   }
2047 }
2048
2049
2050 /**
2051  * Function called when the transport service has received an
2052  * acknowledgement for this communicator (!) via a different return
2053  * path.
2054  *
2055  * Not applicable for TCP.
2056  *
2057  * @param cls closure
2058  * @param sender which peer sent the notification
2059  * @param msg payload
2060  */
2061 static void
2062 enc_notify_cb (void *cls,
2063                const struct GNUNET_PeerIdentity *sender,
2064                const struct GNUNET_MessageHeader *msg)
2065 {
2066   (void) cls;
2067   (void) sender;
2068   (void) msg;
2069   GNUNET_break_op (0);
2070 }
2071
2072
2073 /**
2074  * Signature of the callback passed to #GNUNET_NAT_register() for
2075  * a function to call whenever our set of 'valid' addresses changes.
2076  *
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
2083  */
2084 static void
2085 nat_address_cb (void *cls,
2086                 int add_remove,
2087                 enum GNUNET_NAT_AddressClass ac,
2088                 const struct sockaddr *addr,
2089                 socklen_t addrlen)
2090 {
2091   char *my_addr;
2092   static struct GNUNET_TRANSPORT_AddressIdentifier *ai; // FIXME: store in *ctx of NAT!
2093
2094   if (GNUNET_YES == add_remove)
2095   {
2096     // FIXME: do better job at stringification of @a addr?
2097     GNUNET_asprintf (&my_addr,
2098                      "%s-%s",
2099                      COMMUNICATOR_ADDRESS_PREFIX,
2100                      GNUNET_a2s (addr,
2101                                  addrlen));
2102     // FIXME: translate 'ac' to 'nt'?
2103     ai = GNUNET_TRANSPORT_communicator_address_add (ch,
2104                                                     my_addr,
2105                                                     GNUNET_NT_LOOPBACK, // FIXME: wrong NT!
2106                                                     GNUNET_TIME_UNIT_FOREVER_REL);
2107     GNUNET_free (my_addr);
2108   }
2109   else
2110   {
2111     // FIXME: support removal! => improve NAT API!
2112     GNUNET_TRANSPORT_communicator_address_remove (ai);
2113     ai = NULL;
2114   }
2115 }
2116
2117
2118 /**
2119  * Setup communicator and launch network interactions.
2120  *
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
2125  */
2126 static void
2127 run (void *cls,
2128      char *const *args,
2129      const char *cfgfile,
2130      const struct GNUNET_CONFIGURATION_Handle *c)
2131 {
2132   char *bindto;
2133   struct sockaddr *in;
2134   socklen_t in_len;
2135
2136   (void) cls;
2137   cfg = c;
2138   if (GNUNET_OK !=
2139       GNUNET_CONFIGURATION_get_value_filename (cfg,
2140                                                COMMUNICATOR_CONFIG_SECTION,
2141                                                "BINDTO",
2142                                                &bindto))
2143   {
2144     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2145                                COMMUNICATOR_CONFIG_SECTION,
2146                                "BINDTO");
2147     return;
2148   }
2149   if (GNUNET_OK !=
2150       GNUNET_CONFIGURATION_get_value_number (cfg,
2151                                              COMMUNICATOR_CONFIG_SECTION,
2152                                              "MAX_QUEUE_LENGTH",
2153                                              &max_queue_length))
2154     max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2155
2156   in = tcp_address_to_sockaddr (bindto,
2157                                 &in_len);
2158   if (NULL == in)
2159   {
2160     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2161                 "Failed to setup TCP socket address with path `%s'\n",
2162                 bindto);
2163     GNUNET_free (bindto);
2164     return;
2165   }
2166   listen_sock = GNUNET_NETWORK_socket_create (in->sa_family,
2167                                               SOCK_STREAM,
2168                                               IPPROTO_TCP);
2169   if (NULL == listen_sock)
2170   {
2171     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2172                          "socket");
2173     GNUNET_free (in);
2174     GNUNET_free (bindto);
2175     return;
2176   }
2177   if (GNUNET_OK !=
2178       GNUNET_NETWORK_socket_bind (listen_sock,
2179                                   in,
2180                                   in_len))
2181   {
2182     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2183                               "bind",
2184                               bindto);
2185     GNUNET_NETWORK_socket_close (listen_sock);
2186     listen_sock = NULL;
2187     GNUNET_free (in);
2188     GNUNET_free (bindto);
2189     return;
2190   }
2191   GNUNET_free (in);
2192   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2193               "Bound to `%s'\n",
2194               bindto);
2195   GNUNET_free (bindto);
2196   stats = GNUNET_STATISTICS_create ("C-TCP",
2197                                     cfg);
2198   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
2199                                  NULL);
2200   my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2201   if (NULL == my_private_key)
2202   {
2203     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2204                 _("Transport service is lacking key configuration settings. Exiting.\n"));
2205     GNUNET_SCHEDULER_shutdown ();
2206     return;
2207   }
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,
2212                                                listen_sock,
2213                                                &listen_cb,
2214                                                NULL);
2215   queue_map = GNUNET_CONTAINER_multipeermap_create (10,
2216                                                     GNUNET_NO);
2217   ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2218                                               COMMUNICATOR_CONFIG_SECTION,
2219                                               COMMUNICATOR_ADDRESS_PREFIX,
2220                                               GNUNET_TRANSPORT_CC_RELIABLE,
2221                                               &mq_init,
2222                                               NULL,
2223                                               &enc_notify_cb,
2224                                               NULL);
2225   if (NULL == ch)
2226   {
2227     GNUNET_break (0);
2228     GNUNET_SCHEDULER_shutdown ();
2229     return;
2230   }
2231   nat = GNUNET_NAT_register (cfg,
2232                              COMMUNICATOR_CONFIG_SECTION,
2233                              IPPROTO_TCP,
2234                              1 /* one address */,
2235                              (const struct sockaddr **) &in,
2236                              &in_len,
2237                              &nat_address_cb,
2238                              NULL /* FIXME: support reversal! */,
2239                              NULL /* closure */);
2240 }
2241
2242
2243 /**
2244  * The main function for the UNIX communicator.
2245  *
2246  * @param argc number of arguments from the command line
2247  * @param argv command line arguments
2248  * @return 0 ok, 1 on error
2249  */
2250 int
2251 main (int argc,
2252       char *const *argv)
2253 {
2254   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2255     GNUNET_GETOPT_OPTION_END
2256   };
2257   int ret;
2258
2259   if (GNUNET_OK !=
2260       GNUNET_STRINGS_get_utf8_args (argc, argv,
2261                                     &argc, &argv))
2262     return 2;
2263
2264   ret =
2265       (GNUNET_OK ==
2266        GNUNET_PROGRAM_run (argc, argv,
2267                            "gnunet-communicator-tcp",
2268                            _("GNUnet TCP communicator"),
2269                            options,
2270                            &run,
2271                            NULL)) ? 0 : 1;
2272   GNUNET_free ((void*) argv);
2273   return ret;
2274 }
2275
2276
2277 #if defined(LINUX) && defined(__GLIBC__)
2278 #include <malloc.h>
2279
2280 /**
2281  * MINIMIZE heap size (way below 128k) since this process doesn't need much.
2282  */
2283 void __attribute__ ((constructor))
2284 GNUNET_ARM_memory_init ()
2285 {
2286   mallopt (M_TRIM_THRESHOLD, 4 * 1024);
2287   mallopt (M_TOP_PAD, 1 * 1024);
2288   malloc_trim (0);
2289 }
2290 #endif
2291
2292 /* end of gnunet-communicator-tcp.c */