first draft of UDP communicator
[oweals/gnunet.git] / src / transport / gnunet-communicator-udp.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-udp.c
23  * @brief Transport plugin using UDP.
24  * @author Christian Grothoff
25  *
26  * TODO:
27  * - support DNS names in BINDTO option (#5528)
28  * - support NAT connection reversal method (#5529)
29  * - support other UDP-specific NAT traversal methods 
30  */
31 #include "platform.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_protocols.h"
34 #include "gnunet_signatures.h"
35 #include "gnunet_constants.h"
36 #include "gnunet_nt_lib.h"
37 #include "gnunet_nat_service.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet_transport_communication_service.h"
40
41 /**
42  * How many messages do we keep at most in the queue to the
43  * transport service before we start to drop (default,
44  * can be changed via the configuration file).
45  * Should be _below_ the level of the communicator API, as
46  * otherwise we may read messages just to have them dropped
47  * by the communicator API.
48  */
49 #define DEFAULT_MAX_QUEUE_LENGTH 8
50
51 /**
52  * How often do we rekey based on time (at least)
53  */ 
54 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
55
56 /**
57  * How long do we wait until we must have received the initial KX?
58  */ 
59 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
60
61 /**
62  * How often do we rekey based on number of bytes transmitted?
63  * (additionally randomized).
64  */ 
65 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
66
67 /**
68  * Address prefix used by the communicator.
69  */
70 #define COMMUNICATOR_ADDRESS_PREFIX "udp"
71
72 /**
73  * Configuration section used by the communicator.
74  */
75 #define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
76
77 GNUNET_NETWORK_STRUCT_BEGIN
78
79
80 /**
81  * Signature we use to verify that the ephemeral key was really chosen by
82  * the specified sender.  If possible, the receiver should respond with
83  * a `struct UDPAck` (possibly via backchannel).
84  */
85 struct UdpHandshakeSignature
86 {
87   /**
88    * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE
89    */
90   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
91
92   /**
93    * Identity of the inititor of the UDP connection (UDP client).
94    */ 
95   struct GNUNET_PeerIdentity sender;
96
97   /**
98    * Presumed identity of the target of the UDP connection (UDP server)
99    */ 
100   struct GNUNET_PeerIdentity receiver;
101
102   /**
103    * Ephemeral key used by the @e sender.
104    */ 
105   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
106
107   /**
108    * Monotonic time of @e sender, to possibly help detect replay attacks
109    * (if receiver persists times by sender).
110    */ 
111   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
112 };
113
114
115 /**
116  * "Plaintext" header at beginning of KX message. Followed
117  * by encrypted `struct UDPConfirmation`.
118  */
119 struct InitialKX
120 {
121
122   /**
123    * Ephemeral key for KX.
124    */ 
125   struct GNUNET_CRYPT_EddsaPublicKey ephemeral;
126
127   /**
128    * HMAC for the following encrypted message, using GCM.  HMAC uses
129    * key derived from the handshake with sequence number zero.
130    */ 
131   uint8_t gcm_tag[128/8];
132
133 };
134
135
136 /**
137  * Encrypted continuation of UDP initial handshake, followed
138  * by message header with payload.
139  */
140 struct UDPConfirmation
141 {
142   /**
143    * Sender's identity
144    */
145   struct GNUNET_PeerIdentity sender;
146
147   /**
148    * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE
149    */
150   struct GNUNET_CRYPTO_EddsaSignature sender_sig;
151
152   /**
153    * Monotonic time of @e sender, to possibly help detect replay attacks
154    * (if receiver persists times by sender).
155    */ 
156   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
157
158   /* followed by messages */
159
160   /* padding may follow actual messages */
161 };
162
163
164 /**
165  * UDP key acknowledgement.  May be sent via backchannel. Allows the
166  * sender to use `struct UDPBox` with the acknowledge key henceforth.
167  */ 
168 struct UDPAck
169 {
170
171   /**
172    * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
173    */ 
174   struct GNUNET_MessageHeader header;
175
176   /**
177    * Sequence acknowledgement limit. Specifies current maximum sequence
178    * number supported by receiver.
179    */ 
180   uint32_t sequence_max GNUNET_PACKED;
181   
182   /**
183    * CMAC of the base key being acknowledged.
184    */ 
185   struct GNUNET_HashCode cmac;
186
187 };
188
189
190 /**
191  * UDP message box.  Always sent encrypted, only allowed after
192  * the receiver sent a `struct UDPAck` for the base key!
193  */ 
194 struct UDPBox
195 {
196
197   /**
198    * Key and IV identification code. KDF applied to an acknowledged
199    * base key and a sequence number.  Sequence numbers must be used
200    * monotonically increasing up to the maximum specified in 
201    * `struct UDPAck`. Without further `struct UDPAck`s, the sender
202    * must fall back to sending handshakes!
203    */
204   struct GNUNET_ShortHashCode kid;
205
206   /**
207    * 128-bit authentication tag for the following encrypted message,
208    * from GCM.  MAC starts at the @e body_start that follows and
209    * extends until the end of the UDP payload.  If the @e hmac is
210    * wrong, the receiver should check if the message might be a
211    * `struct UdpHandshakeSignature`.
212    */ 
213   uint8_t gcm_tag[128/8];
214
215   
216 };
217
218
219 GNUNET_NETWORK_STRUCT_END
220
221 /**
222  * Shared secret we generated for a particular sender or receiver.
223  */
224 struct SharedSecret;
225
226
227 /**
228  * Pre-generated "kid" code (key and IV identification code) to
229  * quickly derive master key for a `struct UDPBox`.
230  */
231 struct KeyCacheEntry
232 {
233
234   /**
235    * Kept in a DLL.
236    */
237   struct KeyCacheEntry *next;
238   
239   /**
240    * Kept in a DLL.
241    */
242   struct KeyCacheEntry *prev;
243
244   /**
245    * Key and IV identification code. KDF applied to an acknowledged
246    * base key and a sequence number.  Sequence numbers must be used
247    * monotonically increasing up to the maximum specified in 
248    * `struct UDPAck`. Without further `struct UDPAck`s, the sender
249    * must fall back to sending handshakes!
250    */
251   struct GNUNET_ShortHashCode kid;
252
253   /**
254    * Corresponding shared secret.
255    */
256   struct SharedSecret *ss;
257
258   /**
259    * Sequence number used to derive this entry from master key.
260    */ 
261   uint32_t sequence_number;
262 };
263
264
265 /**
266  * Information we track per sender address we have recently been
267  * in contact with (decryption from sender).
268  */
269 struct SenderAddress;
270
271 /**
272  * Information we track per receiving address we have recently been
273  * in contact with (encryption to receiver).
274  */
275 struct ReceiverAddress;
276
277 /**
278  * Shared secret we generated for a particular sender or receiver.
279  */
280 struct SharedSecret
281 {
282   /**
283    * Kept in a DLL.
284    */
285   struct SharedSecret *next;
286
287   /**
288    * Kept in a DLL.
289    */
290   struct SharedSecret *prev;
291
292   /**
293    * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
294    */
295   struct KeyCacheEntry *kce_head;
296   
297   /**
298    * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
299    */
300   struct KeyCacheEntry *kce_tail;
301
302   /**
303    * Sender we use this shared secret with, or NULL.
304    */
305   struct SenderAddress *sender;
306
307   /**
308    * Receiver we use this shared secret with, or NULL.
309    */
310   struct ReceiverAddress *receiver;
311   
312   /**
313    * Master shared secret.
314    */ 
315   struct GNUNET_HashCode master;
316
317   /**
318    * CMAC is used to identify @e master in ACKs.
319    */ 
320   struct GNUNET_HashCode cmac;
321
322   /**
323    * Up to which sequence number did we use this @e master already?
324    * (for sending or receiving)
325    */ 
326   uint32_t sequence_used;
327
328   /**
329    * Up to which sequence number did the other peer allow us to use
330    * this key, or up to which number did we allow the other peer to
331    * use this key?
332    */
333   uint32_t sequence_allowed;
334 };
335
336
337 /**
338  * Information we track per sender address we have recently been
339  * in contact with (we decrypt messages from the sender).
340  */
341 struct SenderAddress
342 {
343
344   /**
345    * To whom are we talking to.
346    */
347   struct GNUNET_PeerIdentity target;  
348
349   /**
350    * Entry in sender expiration heap.
351    */ 
352   struct GNUNET_CONTAINER_HeapNode *hn;
353
354   /**
355    * Shared secrets we used with @e target, first used is head.
356    */
357   struct SharedSecret *ss_head;
358
359   /**
360    * Shared secrets we used with @e target, last used is tail.
361    */
362   struct SharedSecret *ss_tail;
363   
364   /**
365    * Address of the other peer.
366    */
367   struct sockaddr *address;
368   
369   /**
370    * Length of the address.
371    */
372   socklen_t address_len;
373
374   /**
375    * Timeout for this sender.
376    */
377   struct GNUNET_TIME_Absolute timeout;
378
379   /**
380    * Length of the DLL at @a ss_head.
381    */ 
382   unsigned int num_secrets;
383   
384   /**
385    * Which network type does this queue use?
386    */
387   enum GNUNET_NetworkType nt;
388   
389 };
390
391
392 /**
393  * Information we track per receiving address we have recently been
394  * in contact with (encryption to receiver).
395  */
396 struct ReceiverAddress
397 {
398
399   /**
400    * To whom are we talking to.
401    */
402   struct GNUNET_PeerIdentity target;  
403   
404   /**
405    * Shared secrets we received from @e target, first used is head.
406    */
407   struct SharedSecret *ss_head;
408
409   /**
410    * Shared secrets we received with @e target, last used is tail.
411    */
412   struct SharedSecret *ss_tail;
413
414   /**
415    * Address of the other peer.
416    */
417   struct sockaddr *address;
418   
419   /**
420    * Length of the address.
421    */
422   socklen_t address_len;
423
424   /**
425    * Message queue we are providing for the #ch.
426    */
427   struct GNUNET_MQ_Handle *mq;
428
429   /**
430    * handle for this queue with the #ch.
431    */
432   struct GNUNET_TRANSPORT_QueueHandle *qh;
433
434   /**
435    * Timeout for this receiver address.
436    */
437   struct GNUNET_TIME_Absolute timeout;
438
439   /**
440    * Length of the DLL at @a ss_head.
441    */ 
442   unsigned int num_secrets;
443   
444   /**
445    * Which network type does this queue use?
446    */
447   enum GNUNET_NetworkType nt;
448   
449 };
450
451
452 /**
453  * Cache of pre-generated key IDs.
454  */
455 static struct GNUNET_CONTINER_MultiShortMap *key_cache;
456
457 /**
458  * ID of read task
459  */
460 static struct GNUNET_SCHEDULER_Task *read_task;
461
462 /**
463  * ID of timeout task
464  */
465 static struct GNUNET_SCHEDULER_Task *timeout_task;
466
467 /**
468  * For logging statistics.
469  */
470 static struct GNUNET_STATISTICS_Handle *stats;
471
472 /**
473  * Our environment.
474  */
475 static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
476
477 /**
478  * Receivers (map from peer identity to `struct ReceiverAddress`)
479  */
480 static struct GNUNET_CONTAINER_MultiPeerMap *receivers;
481
482 /**
483  * Senders (map from peer identity to `struct SenderAddress`)
484  */
485 static struct GNUNET_CONTAINER_MultiPeerMap *senders;
486
487 /**
488  * Expiration heap for senders (contains `struct SenderAddress`)
489  */
490 static struct GNUNET_CONTAINER_Heap *senders_heap;
491
492 /**
493  * Expiration heap for receivers (contains `struct ReceiverAddress`)
494  */
495 static struct GNUNET_CONTAINER_Heap *receivers_heap;
496
497 /**
498  * Our socket.
499  */
500 static struct GNUNET_NETWORK_Handle *udp_sock;
501
502 /**
503  * Our public key.
504  */
505 static struct GNUNET_PeerIdentity my_identity;
506
507 /**
508  * Our private key.
509  */
510 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
511
512 /**
513  * Our configuration.
514  */
515 static const struct GNUNET_CONFIGURATION_Handle *cfg;
516
517 /**
518  * Network scanner to determine network types.
519  */
520 static struct GNUNET_NT_InterfaceScanner *is;
521
522 /**
523  * Connection to NAT service.
524  */
525 static struct GNUNET_NAT_Handle *nat;
526
527
528 /**
529  * Functions with this signature are called whenever we need
530  * to close a receiving state due to timeout.
531  *
532  * @param receiver entity to close down
533  */
534 static void
535 receiver_destroy (struct ReceiverAddress *receiver)
536 {
537   struct GNUNET_MQ_Handle *mq;
538   
539   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
540               "Disconnecting receiver for peer `%s'\n",
541               GNUNET_i2s (&receiver->target));
542   if (NULL != (mq = receiver->mq))
543   {
544     receiver->mq = NULL;
545     GNUNET_MQ_destroy (mq);
546   }
547   GNUNET_assert (GNUNET_YES ==
548                  GNUNET_CONTAINER_multipeermap_remove (receivers,
549                                                        &receiver->target,
550                                                        receiver));
551   // FIXME: remove from receiver_heap
552   GNUNET_STATISTICS_set (stats,
553                          "# receivers active",
554                          GNUNET_CONTAINER_multipeermap_size (receivers),
555                          GNUNET_NO);
556   GNUNET_free (receiver->address);
557   GNUNET_free (receiver);
558 }
559
560
561 /**
562  * Free memory used by key cache entry.
563  *
564  * @param kce the key cache entry
565  */ 
566 static void
567 kce_destroy (struct KeyCacheEntry *kce)
568 {
569   struct SharedSecret *ss = kce->ss;
570
571   GNUNET_CONTAINER_DLL_remove (ss->kce_head,
572                                ss->kce_tail,
573                                kce);
574   GNUNET_assert (GNUNET_YES ==
575                  GNUNET_CONTAINER_multishortmap_remove (key_cache,
576                                                         &kce->kid,
577                                                         kce));
578   GNUNET_free (kce);
579 }
580
581
582 /**
583  * Compute @a kid.
584  *
585  * @param msec master secret for HMAC calculation
586  * @param serial number for the @a smac calculation
587  * @param kid[out] where to write the key ID
588  */
589 static void
590 get_kid (const struct GNUNET_HashCode *msec,
591          uint32_t serial,
592          struct GNUNET_ShortHashCode *kid)
593 {
594   uint32_t sid = htonl (serial);
595
596   GNUNET_CRYPTO_hkdf (kid,
597                       sizeof (*kid),
598                       GCRY_MD_SHA512,
599                       GCRY_MD_SHA256,
600                       &sid,
601                       sizeof (sid),
602                       msec,
603                       sizeof (*msec),
604                       "UDP-KID",
605                       strlen ("UDP-KID"),
606                       NULL, 0);
607 }
608
609
610 /**
611  * Setup key cache entry for sequence number @a seq and shared secret @a ss.
612  *
613  * @param ss shared secret
614  * @param seq sequence number for the key cache entry
615  */
616 static void
617 kce_generate (struct SharedSecret *ss,
618               uint32_t seq)
619 {
620   struct KeyCacheEntry *kce;
621
622   GNUNET_assert (0 < seq);
623   kce = GNUNET_new (struct KeyCacheEntry);
624   kce->ss = ss;
625   kce->sequence_number = seq;
626   get_kid (&ss->master,
627            seq,
628            &kce->kid);
629   GNUNET_CONTAINER_DLL_insert (ss->kce_head,
630                                ss->kce_tail,
631                                kce);
632   (void) GNUNET_CONTAINER_multishortmap_put (key_cache,
633                                              &kce->kid,
634                                              kce,
635                                              GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
636   GNUNET_STATISTICS_set (stats,
637                          "# KIDs active",
638                          GNUNET_CONTAINER_multipeermap_size (key_cache),
639                          GNUNET_NO);
640 }
641
642
643 /**
644  * Destroy @a ss and associated key cache entries.
645  *
646  * @param ss shared secret to destroy
647  */
648 static void
649 secret_destroy (struct SharedSecret *ss)
650 {
651   struct SenderAddress *sender;
652   struct ReceiverAddress *receiver;
653   struct KeyCacheEntry *kce;
654
655   if (NULL != (sender = ss->sender))
656   {
657     GNUNET_CONTAINER_DLL_remove (sender->ss_head,
658                                  sender->ss_tail,
659                                  ss);
660     sender->num_secrets--;
661   }
662   if (NULL != (receiver = ss->receiver))
663   {
664     GNUNET_CONTAINER_DLL_remove (receiver->ss_head,
665                                  receiver->ss_tail,
666                                  ss);
667     receiver->num_secrets--;
668   }
669   while (NULL != (kce = ss->kce_head))
670     kce_destroy (kce);
671   GNUNET_STATISTICS_update (stats,
672                             "# Secrets active",
673                             -1,
674                             GNUNET_NO);
675   GNUNET_STATISTICS_set (stats,
676                          "# KIDs active",
677                          GNUNET_CONTAINER_multipeermap_size (key_cache),
678                          GNUNET_NO);
679   GNUNET_free (ss);
680 }
681
682
683 /**
684  * Functions with this signature are called whenever we need
685  * to close a sender's state due to timeout.
686  *
687  * @param sender entity to close down
688  */
689 static void
690 sender_destroy (struct SenderAddress *sender)
691 {
692   GNUNET_assert (GNUNET_YES ==
693                  GNUNET_CONTAINER_multipeermap_remove (senders,
694                                                        &sender->target,
695                                                        sender));
696   // FIXME: remove from sender_heap
697   GNUNET_STATISTICS_set (stats,
698                          "# senders active",
699                          GNUNET_CONTAINER_multipeermap_size (senders),
700                          GNUNET_NO);
701   GNUNET_free (sender->address);
702   GNUNET_free (sender);
703 }
704
705
706 /**
707  * Compute @a smac over @a buf.
708  *
709  * @param msec master secret for HMAC calculation
710  * @param serial number for the @a smac calculation
711  * @param buf buffer to MAC
712  * @param buf_size number of bytes in @a buf
713  * @param smac[out] where to write the HMAC
714  */
715 static void
716 get_hmac (const struct GNUNET_HashCode *msec,
717           uint32_t serial,
718           const void *buf,
719           size_t buf_size,
720           struct GNUNET_ShortHashCode *smac)
721 {
722   uint32_t sid = htonl (serial);
723
724   GNUNET_CRYPTO_hkdf (smac,
725                       sizeof (*smac),
726                       GCRY_MD_SHA512,
727                       GCRY_MD_SHA256,
728                       &sid,
729                       sizeof (sid),
730                       msec,
731                       sizeof (*msec),
732                       "UDP-HMAC",
733                       strlen ("UDP-HMAC"),
734                       NULL, 0);
735 }
736
737
738 /**
739  * Compute @a key and @a iv.
740  *
741  * @param msec master secret for calculation
742  * @param serial number for the @a smac calculation
743  * @param key[out] where to write the decrption key
744  * @param iv[out] where to write the IV
745  */
746 static void
747 get_iv_key (const struct GNUNET_HashCode *msec,
748             uint32_t serial,
749             char key[256/8],
750             char iv[96/8])
751 {
752   uint32_t sid = htonl (serial);
753   char res[sizeof(key) + sizeof (iv)];
754
755   GNUNET_CRYPTO_hkdf (res,
756                       sizeof (res),
757                       GCRY_MD_SHA512,
758                       GCRY_MD_SHA256,
759                       &sid,
760                       sizeof (sid),
761                       msec,
762                       sizeof (*msec),
763                       "UDP-IV-KEY",
764                       strlen ("UDP-IV-KEY"),
765                       NULL, 0);
766   memcpy (key,
767           sid,
768           sizeof (key));
769   memcpy (iv,
770           &sid[sizeof(key)],
771           sizeof (iv));
772 }
773
774
775 /**
776  * Increment sender timeout due to activity.
777  *
778  * @param sender address for which the timeout should be rescheduled
779  */
780 static void
781 reschedule_sender_timeout (struct SenderAddress *sender)
782 {
783   sender->timeout
784     = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
785   // FIXME: update heap!
786 }
787
788
789 /**
790  * Increment receiver timeout due to activity.
791  *
792  * @param receiver address for which the timeout should be rescheduled
793  */
794 static void
795 reschedule_receiver_timeout (struct ReceiverAddress *receiver)
796 {
797   receiver->timeout
798     = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
799   // FIXME: update heap!
800 }
801
802
803 /**
804  * Calcualte cmac from master in @a ss.
805  *
806  * @param ss[in,out] data structure to complete
807  */
808 static void
809 calculate_cmac (struct SharedSecret *ss)
810 {
811   GNUNET_CRYPTO_hkdf (&ss->cmac,
812                       sizeof (ss->cmac),
813                       GCRY_MD_SHA512,
814                       GCRY_MD_SHA256,
815                       "CMAC",
816                       strlen ("CMAC"),
817                       &ss->master,
818                       sizeof (ss->master),
819                       "UDP-CMAC",
820                       strlen ("UDP-CMAC"),
821                       NULL, 0);
822 }
823
824
825 /**
826  * We received @a plaintext_len bytes of @a plaintext from a @a sender.
827  * Pass it on to CORE.  
828  *
829  * @param queue the queue that received the plaintext
830  * @param plaintext the plaintext that was received
831  * @param plaintext_len number of bytes of plaintext received
832  */ 
833 static void
834 pass_plaintext_to_core (struct SenderAddress *sender,
835                         const void *plaintext,
836                         size_t plaintext_len)
837 {
838   const struct GNUNET_MessageHeader *hdr = plaintext;
839
840   while (ntohs (hdr->size) < plaintext_len)
841   {
842     GNUNET_STATISTICS_update (stats,
843                               "# bytes given to core",
844                               ntohs (hdr->size),
845                               GNUNET_NO);
846     (void) GNUNET_TRANSPORT_communicator_receive (ch,
847                                                   &queue->target,
848                                                   hdr,
849                                                   NULL /* no flow control possible */,
850                                                   NULL);
851     /* move on to next message, if any */
852     plaintext_len -= ntohs (hdr->size);
853     if (plaintext_len < sizeof (*hdr))
854       break;
855     hdr = plaintext + ntohs (hdr->size);
856   }
857   GNUNET_STATISTICS_update (stats,
858                             "# bytes padding discarded",
859                             plaintext_len,
860                             GNUNET_NO);
861 }
862
863
864 /**
865  * Setup @a cipher based on shared secret @a msec and
866  * serial number @a serial.
867  *
868  * @param msec master shared secret
869  * @param serial serial number of cipher to set up
870  * @param cipher[out] cipher to initialize
871  */
872 static void
873 setup_cipher (const struct GNUNET_HashCode *msec,
874               uint32_t serial,
875               gcry_cipher_hd_t *cipher)
876 {
877   char key[256/8];
878   char iv[96/8];
879
880   gcry_cipher_open (cipher,
881                     GCRY_CIPHER_AES256 /* low level: go for speed */,
882                     GCRY_CIPHER_MODE_GCM,
883                     0 /* flags */);
884   get_iv_key (msec,
885               serial,
886               key,
887               iv);
888   gcry_cipher_setkey (*cipher,
889                       key,
890                       sizeof (key));
891   gcry_cipher_setiv (*cipher,
892                      iv,
893                      sizeof (iv));
894 }
895
896
897 /**
898  * Try to decrypt @a buf using shared secret @a ss and key/iv 
899  * derived using @a serial.
900  *
901  * @param ss shared secret
902  * @param tag GCM authentication tag
903  * @param serial serial number to use
904  * @param in_buf input buffer to decrypt
905  * @param in_buf_size number of bytes in @a in_buf and available in @a out_buf
906  * @param out_buf where to write the result
907  * @return #GNUNET_OK on success
908  */
909 static int
910 try_decrypt (const struct SharedSecret *ss,
911              char tag[128/8],
912              uint32_t serial,
913              const char *in_buf,
914              size_t in_buf_size,
915              char *out_buf)
916 {
917   gcry_cipher_hd_t cipher;
918
919   setup_cipher (&ss->master,
920                 serial,
921                 &cipher);
922   GNUNET_assert (0 ==
923                  gcry_cipher_decrypt (cipher,
924                                       in_buf,
925                                       in_buf_size,
926                                       out_buf,
927                                       in_buf_size));
928   if (0 !=
929       gcry_cipher_checktag (cipher,
930                             tag,
931                             sizeof (tag)))
932   {
933     gcry_cipher_close (cipher);
934     GNUNET_STATISTICS_update (stats,
935                               "# AEAD authentication failures",
936                               1,
937                               GNUNET_NO);
938     return GNUNET_SYSERR;
939   }
940   gcry_cipher_close (cipher);
941   return GNUNET_OK;
942 }
943
944
945 /**
946  * Setup shared secret for decryption.
947  *
948  * @param ephemeral ephemeral key we received from the other peer
949  * @return new shared secret
950  */
951 static struct SharedSecret *
952 setup_shared_secret_dec (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
953 {
954   struct SharedSecret *ss;
955
956   ss = GNUNET_new (struct SharedSecret);
957   GNUNET_CRYPTO_eddsa_ecdh (my_private_key,
958                             ephemeral,
959                             &ss->master);
960   return ss;
961 }
962
963
964 /**
965  * Setup shared secret for encryption.
966  *
967  * @param ephemeral ephemeral key we are sending to the other peer
968  * @param receiver[in,out] queue to initialize encryption key for
969  * @return new shared secret
970  */
971 static struct SharedSecret *
972 setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral,
973                          struct ReceiverAddress *receiver)
974 {
975   struct SharedSecret *ss;
976
977   ss = GNUNET_new (struct SharedSecret);
978   GNUNET_CRYPTO_ecdh_eddsa (ephemeral,
979                             &receiver->target.public_key,
980                             &ss->master);
981   calculcate_cmac (ss);
982   ss->receiver = receiver;
983   GNUNET_CONTAINER_DLL_insert (receiver->ss_head,
984                                receiver->ss_tail,
985                                ss);
986   receiver->num_secrets++;
987   GNUNET_STATISTICS_update (stats,
988                             "# Secrets active",
989                             1,
990                             GNUNET_NO);
991   return ss;
992 }
993                 
994
995 /**
996  * Test if we have received a valid message in plaintext.
997  * If so, handle it.
998  *
999  * @param sender peer to process inbound plaintext for
1000  * @param buf buffer we received
1001  * @param buf_size number of bytes in @a buf
1002  */ 
1003 static void
1004 try_handle_plaintext (struct SenderAddress *sender,
1005                       const void *buf,
1006                       size_t buf_size)
1007 {
1008   const struct GNUNET_MessageHeader *hdr
1009     = (const struct GNUNET_MessageHeader *) queue->pread_buf;
1010   const struct UDPAck *ack
1011     = (const struct UDPAck *) queue->pread_buf;
1012   uint16_t type;
1013
1014   if (sizeof (*hdr) > buf_size)
1015     return; /* not even a header */
1016   if (ntohs (hdr->size) > buf_size)
1017     return 0; /* not even a header */
1018   type = ntohs (hdr->type);
1019   switch (type)
1020   {
1021   case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK:
1022     /* lookup master secret by 'cmac', then update sequence_max */
1023     for (struct SharedSecret *ss = sender->ss_head;
1024          NULL != ss;
1025          ss = ss->next)
1026     {
1027       if (0 == memcmp (&ack->cmac,
1028                        &ss->cmac,
1029                        sizeof (ss->cmac)))
1030       {
1031         ss->sequence_allowed = GNUNET_MAX (ss->sequence_allowed,
1032                                            ntohl (ack->sequence_max));
1033         /* move ss to head to avoid discarding it anytime soon! */
1034         GNUNET_CONTAINER_DLL_remove (sender->ss_head,
1035                                      sender->ss_tail,
1036                                      ss);
1037         GNUNET_CONTAINER_DLL_insert (sender->ss_head,
1038                                      sender->ss_tail,
1039                                      ss);
1040         break;
1041       }
1042     }
1043     /* There could be more messages after the ACK, handle those as well */
1044     buf += ntohs (hdr->size);
1045     buf_size -= ntohs (hdr->size);
1046     pass_plaintext_to_core (sender,
1047                             buf,
1048                             buf_size);
1049     break;
1050   default:
1051     pass_plaintext_to_core (sender,
1052                             buf,
1053                             buf_size);
1054   }
1055 }
1056
1057
1058 /**
1059  * We established a shared secret with a sender. We should try to send
1060  * the sender an `struct UDPAck` at the next opportunity to allow the
1061  * sender to use @a ss longer (assuming we did not yet already
1062  * recently).
1063  */
1064 static void
1065 consider_ss_ack (struct SharedSecret *ss)
1066 {
1067   GNUNET_assert (NULL != ss->sender);
1068   for (uint32_t i=1;i<0 /* FIXME: ack-based! */;i++)
1069     kce_generate (ss,
1070                   i);
1071   // FIXME: consider generating ACK and more KCEs for ss!
1072 }
1073
1074
1075 /**
1076  * We received a @a box with matching @a kce.  Decrypt and process it.
1077  *
1078  * @param box the data we received
1079  * @param box_len number of bytes in @a box
1080  * @param kce key index to decrypt @a box
1081  */ 
1082 static void
1083 decrypt_box (const struct UDPBox *box,
1084              size_t box_len,
1085              struct KeyCacheEntry *kce)
1086 {
1087   struct SharedSecret *ss = kce->ss;
1088   gcry_cipher_hd_t cipher;
1089   char out_buf[box_len - sizeof (*box)];
1090
1091   GNUNET_assert (NULL != ss->sender);
1092   if (GNUNET_OK !=
1093       try_decrypt (ss,
1094                    box->gcm_tag,
1095                    kce->sequence_number,
1096                    box_len - sizeof (*box),
1097                    out_buf,
1098                    sizeof (out_buf)))
1099   {
1100     GNUNET_STATISTICS_update (stats,
1101                               "# Decryption failures with valid KCE",
1102                               1,
1103                               GNUNET_NO);
1104     kce_destroy (kce);
1105     return;
1106   }
1107   kce_destroy (kce);
1108   GNUNET_STATISTICS_update (stats,
1109                             "# bytes decrypted with BOX",
1110                             sizeof (out_buf),
1111                             GNUNET_NO);
1112   try_handle_plaintext (ss->sender,
1113                         out_buf,
1114                         sizeof (out_buf));
1115   consider_ss_ack (ss);
1116 }
1117
1118
1119 /**
1120  * Socket read task. 
1121  *
1122  * @param cls NULL
1123  */
1124 static void
1125 sock_read (void *cls)
1126 {
1127   struct sockaddr_storage sa;
1128   socklen_t salen = sizeof (sa);
1129   char buf[UINT16_MAX];
1130   ssize_t rcvd;
1131
1132   (void) cls;
1133   read_task
1134       = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1135                                        udp_sock,
1136                                        &sock_read,
1137                                        NULL);
1138   rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
1139                                          buf,
1140                                          sizeof (buf),
1141                                          (struct sockaddr *) &sa,
1142                                          &salen);
1143   if (-1 == rcvd)
1144   {
1145     GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
1146                          "recv");
1147     return;
1148   }
1149   /* first, see if it is a UDPBox */
1150   if (rcvd > sizeof (struct UDPBox))
1151   {
1152     const struct UDPBox *box;
1153     struct KeyCacheEntry *kce;
1154
1155     box = (const struct UDPBox *) buf;
1156     kce = GNUNET_CONTAINER_multihashmap_get (key_cache,
1157                                              &box->kid);
1158     if (NULL != kce)
1159     {
1160       decrypt_box (box,
1161                    (size_t) rcvd,
1162                    kce);
1163       return;
1164     }
1165   }
1166   /* next, test if it is a KX */
1167   if (rcvd < sizeof (struct UDPConfirmation) + sizeof (struct InitialKX))
1168   {
1169     GNUNET_STATISTICS_update (stats,
1170                               "# messages dropped (no kid, too small for KX)",
1171                               1,
1172                               GNUNET_NO);
1173     return;
1174   }
1175
1176   {
1177     const struct InitialKX *kx;
1178     struct SharedSecret *ss;
1179     char pbuf[rcvd - sizeof (struct InitialKX)];
1180     const struct UDPConfirmation *uc;
1181     struct SenderAddress *sender;
1182
1183     kx = (const struct InitialKX *) buf;
1184     ss = setup_shared_secret_dec (&kx->ephemral);
1185     if (GNUNET_OK !=
1186         try_decrypt (ss,
1187                      0,
1188                      kx->gcm_tag,
1189                      &buf[sizeof (*kx)],
1190                      (const struct GNUNET_CRYPTO_EcdhePublicKey *) buf,
1191                      pbuf))
1192     {
1193       GNUNET_free (ss);
1194       GNUNET_STATISTICS_update (stats,
1195                                 "# messages dropped (no kid, AEAD decryption failed)",
1196                                 1,
1197                                 GNUNET_NO);
1198       return;
1199     }
1200     uc = (const struct UDPConfirmation *) pbuf;
1201     if (GNUNET_OK !=
1202         verify_confirmation (&kx->ephemeral,
1203                              uc))
1204     {
1205       GNUNET_break_op (0);
1206       GNUNET_free (ss);
1207       GNUNET_STATISTICS_update (stats,
1208                                 "# messages dropped (sender signature invalid)",
1209                                 1,
1210                                 GNUNET_NO);
1211       return;
1212     }
1213     calculcate_cmac (ss);
1214     sender = setup_sender (&uc->sender,
1215                            (const struct sockaddr *) &sa,
1216                            salen);
1217     ss->sender = sender;
1218     GNUNET_CONTAINER_DLL_insert (sender->ss_head,
1219                                  sender->ss_tail,
1220                                  ss);
1221     sender->num_secrets++;
1222     GNUNET_STATISTICS_update (stats,
1223                               "# Secrets active",
1224                               1,
1225                               GNUNET_NO);
1226     GNUNET_STATISTICS_update (stats,
1227                               "# bytes decrypted without BOX",
1228                               sizeof (pbuf) - sizeof (*uc),
1229                               GNUNET_NO);
1230     try_handle_plaintext (sender,
1231                           &uc[1],
1232                           sizeof (pbuf) - sizeof (*uc));
1233     consider_ss_ack (ss);
1234     if (sender->num_secrets > MAX_SECRETS)
1235       secret_destroy (sender->ss_tail);
1236   }
1237 }
1238
1239
1240 /**
1241  * Convert UDP bind specification to a `struct sockaddr *`
1242  *
1243  * @param bindto bind specification to convert
1244  * @param[out] sock_len set to the length of the address
1245  * @return converted bindto specification
1246  */
1247 static struct sockaddr *
1248 udp_address_to_sockaddr (const char *bindto,
1249                          socklen_t *sock_len)
1250 {
1251   struct sockaddr *in;
1252   unsigned int port;
1253   char dummy[2];
1254   char *colon;
1255   char *cp;
1256   
1257   if (1 == SSCANF (bindto,
1258                    "%u%1s",
1259                    &port,
1260                    dummy))
1261   {
1262     /* interpreting value as just a PORT number */
1263     if (port > UINT16_MAX)
1264     {
1265       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1266                   "BINDTO specification `%s' invalid: value too large for port\n",
1267                   bindto);
1268       return NULL;
1269     }
1270     if (GNUNET_YES ==
1271         GNUNET_CONFIGURATION_get_value_yesno (cfg,
1272                                               COMMUNICATOR_CONFIG_SECTION,
1273                                               "DISABLE_V6"))
1274     {
1275       struct sockaddr_in *i4;
1276       
1277       i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
1278       i4->sin_family = AF_INET;
1279       i4->sin_port = htons ((uint16_t) port);
1280       *sock_len = sizeof (struct sockaddr_in);
1281       in = (struct sockaddr *) i4;
1282     }
1283     else
1284     {
1285       struct sockaddr_in6 *i6;
1286       
1287       i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
1288       i6->sin6_family = AF_INET6;
1289       i6->sin6_port = htons ((uint16_t) port);
1290       *sock_len = sizeof (struct sockaddr_in6);
1291       in = (struct sockaddr *) i6;
1292     }
1293     return in;
1294   }
1295   cp = GNUNET_strdup (bindto);
1296   colon = strrchr (cp, ':');
1297   if (NULL != colon)
1298   {
1299     /* interpet value after colon as port */
1300     *colon = '\0';
1301     colon++;
1302     if (1 == SSCANF (colon,
1303                      "%u%1s",
1304                      &port,
1305                      dummy))
1306     {
1307       /* interpreting value as just a PORT number */
1308       if (port > UINT16_MAX)
1309       {
1310         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1311                     "BINDTO specification `%s' invalid: value too large for port\n",
1312                     bindto);
1313         GNUNET_free (cp);
1314         return NULL;
1315       }
1316     }
1317     else
1318     {
1319       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1320                   "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1321                   bindto);
1322       GNUNET_free (cp);
1323       return NULL;
1324     }
1325   }
1326   else
1327   {
1328     /* interpret missing port as 0, aka pick any free one */
1329     port = 0;
1330   }
1331   {
1332     /* try IPv4 */
1333     struct sockaddr_in v4;
1334
1335     if (1 == inet_pton (AF_INET,
1336                         cp,
1337                         &v4))
1338     {
1339       v4.sin_port = htons ((uint16_t) port);
1340       in = GNUNET_memdup (&v4,
1341                           sizeof (v4));
1342       *sock_len = sizeof (v4);
1343       GNUNET_free (cp);
1344       return in;
1345     }
1346   }
1347   {
1348     /* try IPv6 */
1349     struct sockaddr_in6 v6;
1350     const char *start;
1351
1352     start = cp;
1353     if ( ('[' == *cp) &&
1354          (']' == cp[strlen (cp)-1]) )
1355     {
1356       start++; /* skip over '[' */
1357       cp[strlen (cp) -1] = '\0'; /* eat ']' */
1358     }
1359     if (1 == inet_pton (AF_INET6,
1360                         start,
1361                         &v6))
1362     {
1363       v6.sin6_port = htons ((uint16_t) port);
1364       in = GNUNET_memdup (&v6,
1365                           sizeof (v6));
1366       *sock_len = sizeof (v6);
1367       GNUNET_free (cp);
1368       return in;
1369     }
1370   }
1371   /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
1372   GNUNET_free (cp);
1373   return NULL;
1374 }
1375
1376
1377 #if 0
1378 /**
1379  *
1380  * 
1381  */
1382 static void
1383 XXX_write (void *cls)
1384 {
1385   ssize_t sent;
1386
1387   sent = GNUNET_NETWORK_socket_sendto (udp_sock,
1388                                        );
1389   if (-1 == sent)
1390   {
1391     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1392                          "send");
1393     return;                      
1394   }
1395 }
1396 #endif
1397
1398
1399 /**
1400  * Signature of functions implementing the sending functionality of a
1401  * message queue.
1402  *
1403  * @param mq the message queue
1404  * @param msg the message to send
1405  * @param impl_state our `struct ReceiverAddress`
1406  */
1407 static void
1408 mq_send (struct GNUNET_MQ_Handle *mq,
1409          const struct GNUNET_MessageHeader *msg,
1410          void *impl_state)
1411 {
1412   struct ReceiverAddress *receiver = impl_state;
1413   uint16_t msize = ntohs (msg->size);
1414
1415   GNUNET_assert (mq == receiver->mq);
1416   // FIXME: pick encryption method, encrypt and transmit and call MQ-send-contiue!!
1417
1418 #if 0
1419   /* compute 'tc' and append in encrypted format to cwrite_buf */
1420   tc.sender = my_identity;
1421   tc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1422   ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE);
1423   ths.purpose.size = htonl (sizeof (ths));
1424   ths.sender = my_identity;
1425   ths.receiver = queue->target;
1426   ths.ephemeral = *epub;
1427   ths.monotonic_time = tc.monotonic_time;
1428   GNUNET_assert (GNUNET_OK ==
1429                  GNUNET_CRYPTO_eddsa_sign (my_private_key,
1430                                            &ths.purpose,
1431                                            &tc.sender_sig));
1432   GNUNET_assert (0 ==
1433                  gcry_cipher_encrypt (queue->out_cipher,
1434                                       &queue->cwrite_buf[queue->cwrite_off],
1435                                       sizeof (tc),
1436                                       &tc,
1437                                       sizeof (tc)));
1438 #endif
1439
1440
1441 }
1442
1443
1444 /**
1445  * Signature of functions implementing the destruction of a message
1446  * queue.  Implementations must not free @a mq, but should take care
1447  * of @a impl_state.
1448  *
1449  * @param mq the message queue to destroy
1450  * @param impl_state our `struct ReceiverAddress`
1451  */
1452 static void
1453 mq_destroy (struct GNUNET_MQ_Handle *mq,
1454             void *impl_state)
1455 {
1456   struct ReceiverAddress *receiver = impl_state;
1457
1458   if (mq == receiver->mq)
1459   {
1460     receiver->mq = NULL;
1461     receiver_destroy (receiver);
1462   }
1463 }
1464
1465
1466 /**
1467  * Implementation function that cancels the currently sent message.
1468  *
1469  * @param mq message queue
1470  * @param impl_state our `struct RecvierAddress`
1471  */
1472 static void
1473 mq_cancel (struct GNUNET_MQ_Handle *mq,
1474            void *impl_state)
1475 {
1476   /* Cancellation is impossible with UDP; bail */
1477   GNUNET_assert (0);
1478 }
1479
1480
1481 /**
1482  * Generic error handler, called with the appropriate
1483  * error code and the same closure specified at the creation of
1484  * the message queue.
1485  * Not every message queue implementation supports an error handler.
1486  *
1487  * @param cls our `struct ReceiverAddress`
1488  * @param error error code
1489  */
1490 static void
1491 mq_error (void *cls,
1492           enum GNUNET_MQ_Error error)
1493 {
1494   struct ReceiverAddress *receiver = cls;
1495
1496   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1497               "MQ error in queue to %s: %d\n",
1498               GNUNET_i2s (&receiver->target),
1499               (int) error);
1500   receiver_destroy (receiver);
1501 }
1502
1503
1504 /**
1505  * Setup a receiver for transmission.  Setup the MQ processing and
1506  * inform transport that the queue is ready. 
1507  *
1508  * @param 
1509  */ 
1510 static struct ReceiverAddress *
1511 receiver_setup (const struct GNUNET_PeerIdentity *target,
1512                 const struct sockddr *address,
1513                 socklen_t address_len)
1514 {
1515   struct ReceiverAddress *receiver;
1516
1517   receiver = GNUNET_new (struct ReceiverAddress);
1518   receiver->address = GNUNET_memdup (address,
1519                                      address_len);
1520   receiver->address_len = address_len;
1521   receiver->target = *target;
1522   receiver->nt = GNUNET_NT_scanner_get_type (is,
1523                                              address,
1524                                              address_len);
1525   (void) GNUNET_CONTAINER_multipeermap_put (receivers,
1526                                             &receiver->target,
1527                                             receiver,
1528                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1529   // FIXME: add to receiver heap!
1530   GNUNET_STATISTICS_set (stats,
1531                          "# receivers active",
1532                          GNUNET_CONTAINER_multipeermap_size (receivers),
1533                          GNUNET_NO);
1534   receiver->timeout
1535     = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1536   receiver->mq
1537     = GNUNET_MQ_queue_for_callbacks (&mq_send,
1538                                      &mq_destroy,
1539                                      &mq_cancel,
1540                                      receiver,
1541                                      NULL,
1542                                      &mq_error,
1543                                      receiver);
1544   {
1545     char *foreign_addr;
1546
1547     switch (address->sa_family)
1548     {
1549     case AF_INET:
1550       GNUNET_asprintf (&foreign_addr,
1551                        "%s-%s",
1552                        COMMUNICATOR_ADDRESS_PREFIX,
1553                        GNUNET_a2s(queue->address,
1554                                   queue->address_len));
1555       break;
1556     case AF_INET6:
1557       GNUNET_asprintf (&foreign_addr,
1558                        "%s-%s",
1559                        COMMUNICATOR_ADDRESS_PREFIX,
1560                        GNUNET_a2s(queue->address,
1561                                   queue->address_len));
1562       break;
1563     default:
1564       GNUNET_assert (0);
1565     }
1566     queue->qh
1567       = GNUNET_TRANSPORT_communicator_mq_add (ch,
1568                                               &receiver->target,
1569                                               foreign_addr,
1570                                               1200 /* FIXME: MTU OK? */,
1571                                               queue->nt,
1572                                               GNUNET_TRANSPORT_CS_OUTBOUND,
1573                                               queue->mq);
1574     GNUNET_free (foreign_addr);
1575   }
1576 }
1577
1578
1579 /**
1580  * Function called by the transport service to initialize a
1581  * message queue given address information about another peer.
1582  * If and when the communication channel is established, the
1583  * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
1584  * to notify the service that the channel is now up.  It is
1585  * the responsibility of the communicator to manage sane
1586  * retries and timeouts for any @a peer/@a address combination
1587  * provided by the transport service.  Timeouts and retries
1588  * do not need to be signalled to the transport service.
1589  *
1590  * @param cls closure
1591  * @param peer identity of the other peer
1592  * @param address where to send the message, human-readable
1593  *        communicator-specific format, 0-terminated, UTF-8
1594  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
1595  */
1596 static int
1597 mq_init (void *cls,
1598          const struct GNUNET_PeerIdentity *peer,
1599          const char *address)
1600 {
1601   struct ReceiverAddress *receiver;
1602   const char *path;
1603   struct sockaddr *in;
1604   socklen_t in_len;
1605   
1606   if (0 != strncmp (address,
1607                     COMMUNICATOR_ADDRESS_PREFIX "-",
1608                     strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1609   {
1610     GNUNET_break_op (0);
1611     return GNUNET_SYSERR;
1612   }
1613   path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1614   in = udp_address_to_sockaddr (path,
1615                                 &in_len);  
1616   receiver = receiver_setup (peer,
1617                              in,
1618                              in_len);
1619   return GNUNET_OK;  
1620 }
1621
1622
1623 /**
1624  * Iterator over all receivers to clean up.
1625  *
1626  * @param cls NULL
1627  * @param target unused
1628  * @param value the queue to destroy
1629  * @return #GNUNET_OK to continue to iterate
1630  */
1631 static int
1632 get_receiver_delete_it (void *cls,
1633                         const struct GNUNET_PeerIdentity *target,
1634                         void *value)
1635 {
1636   struct ReceiverAddress *receiver = value;
1637
1638   (void) cls;
1639   (void) target;
1640   receiver_destroy (receiver);
1641   return GNUNET_OK;
1642 }
1643
1644
1645 /**
1646  * Iterator over all senders to clean up.
1647  *
1648  * @param cls NULL
1649  * @param target unused
1650  * @param value the queue to destroy
1651  * @return #GNUNET_OK to continue to iterate
1652  */
1653 static int
1654 get_receiver_delete_it (void *cls,
1655                         const struct GNUNET_PeerIdentity *target,
1656                         void *value)
1657 {
1658   struct SenderAddress *sender = value;
1659
1660   (void) cls;
1661   (void) target;
1662   sender_destroy (sender);
1663   return GNUNET_OK;
1664 }
1665
1666
1667 /**
1668  * Shutdown the UNIX communicator.
1669  *
1670  * @param cls NULL (always)
1671  */
1672 static void
1673 do_shutdown (void *cls)
1674 {
1675   if (NULL != nat)
1676   {
1677      GNUNET_NAT_unregister (nat);
1678      nat = NULL;
1679   }
1680   if (NULL != read_task)
1681   {
1682     GNUNET_SCHEDULER_cancel (read_task);
1683     read_task = NULL;
1684   }
1685   if (NULL != udp_sock)
1686   {
1687     GNUNET_break (GNUNET_OK ==
1688                   GNUNET_NETWORK_socket_close (udp_sock));
1689     udp_sock = NULL;
1690   }
1691   GNUNET_CONTAINER_multipeermap_iterate (receivers,
1692                                          &get_receiver_delete_it,
1693                                          NULL);
1694   GNUNET_CONTAINER_multipeermap_destroy (receivers);
1695   GNUNET_CONTAINER_multipeermap_iterate (senders,
1696                                          &get_sender_delete_it,
1697                                          NULL);
1698   GNUNET_CONTAINER_multipeermap_destroy (senders);
1699   GNUNET_CONTAINER_multishortmap_destroy (key_cache);
1700   GNUNET_CONTAINER_heap_destroy (senders_heap);
1701   GNUNET_CONTAINER_heap_destroy (receivers_heap);
1702   if (NULL != ch)
1703   {
1704     GNUNET_TRANSPORT_communicator_disconnect (ch);
1705     ch = NULL;
1706   }
1707   if (NULL != stats)
1708   {
1709     GNUNET_STATISTICS_destroy (stats,
1710                                GNUNET_NO);
1711     stats = NULL;
1712   }
1713   if (NULL != my_private_key)
1714   {
1715     GNUNET_free (my_private_key);
1716     my_private_key = NULL;
1717   }
1718   if (NULL != is)
1719   {
1720      GNUNET_NT_scanner_done (is);
1721      is = NULL;
1722   }
1723 }
1724
1725
1726 /**
1727  * Function called when the transport service has received an
1728  * acknowledgement for this communicator (!) via a different return
1729  * path.
1730  *
1731  * Not applicable for UDP.
1732  *
1733  * @param cls closure
1734  * @param sender which peer sent the notification
1735  * @param msg payload
1736  */
1737 static void
1738 enc_notify_cb (void *cls,
1739                const struct GNUNET_PeerIdentity *sender,
1740                const struct GNUNET_MessageHeader *msg)
1741 {
1742   (void) cls;
1743   (void) sender;
1744   (void) msg;
1745   GNUNET_break_op (0);
1746 }
1747
1748
1749 /**
1750  * Signature of the callback passed to #GNUNET_NAT_register() for
1751  * a function to call whenever our set of 'valid' addresses changes.
1752  *
1753  * @param cls closure
1754  * @param app_ctx[in,out] location where the app can store stuff
1755  *                  on add and retrieve it on remove
1756  * @param add_remove #GNUNET_YES to add a new public IP address, 
1757  *                   #GNUNET_NO to remove a previous (now invalid) one
1758  * @param ac address class the address belongs to
1759  * @param addr either the previous or the new public IP address
1760  * @param addrlen actual length of the @a addr
1761  */
1762 static void
1763 nat_address_cb (void *cls,
1764                 void **app_ctx,
1765                 int add_remove,
1766                 enum GNUNET_NAT_AddressClass ac,
1767                 const struct sockaddr *addr,
1768                 socklen_t addrlen)
1769 {
1770   char *my_addr;
1771   struct GNUNET_TRANSPORT_AddressIdentifier *ai;
1772
1773   if (GNUNET_YES == add_remove)
1774   {
1775     enum GNUNET_NetworkType nt;
1776
1777     GNUNET_asprintf (&my_addr,
1778                      "%s-%s",
1779                      COMMUNICATOR_ADDRESS_PREFIX,
1780                      GNUNET_a2s (addr,
1781                                  addrlen));
1782     nt = GNUNET_NT_scanner_get_type (is,
1783                                      addr,
1784                                      addrlen); 
1785     ai = GNUNET_TRANSPORT_communicator_address_add (ch,
1786                                                     my_addr,
1787                                                     nt,
1788                                                     GNUNET_TIME_UNIT_FOREVER_REL);
1789     GNUNET_free (my_addr);
1790     *app_ctx = ai;
1791   }
1792   else
1793   {
1794     ai = *app_ctx;
1795     GNUNET_TRANSPORT_communicator_address_remove (ai);
1796     *app_ctx = NULL;
1797   }
1798 }
1799
1800
1801 /**
1802  * Setup communicator and launch network interactions.
1803  *
1804  * @param cls NULL (always)
1805  * @param args remaining command-line arguments
1806  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1807  * @param c configuration
1808  */
1809 static void
1810 run (void *cls,
1811      char *const *args,
1812      const char *cfgfile,
1813      const struct GNUNET_CONFIGURATION_Handle *c)
1814 {
1815   char *bindto;
1816   struct sockaddr *in;
1817   socklen_t in_len;
1818   struct sockaddr_storage in_sto;
1819   socklen_t sto_len;
1820   
1821   (void) cls;
1822   cfg = c;
1823   if (GNUNET_OK !=
1824       GNUNET_CONFIGURATION_get_value_filename (cfg,
1825                                                COMMUNICATOR_CONFIG_SECTION,
1826                                                "BINDTO",
1827                                                &bindto))
1828   {
1829     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
1830                                COMMUNICATOR_CONFIG_SECTION,
1831                                "BINDTO");
1832     return;
1833   }
1834   if (GNUNET_OK !=
1835       GNUNET_CONFIGURATION_get_value_number (cfg,
1836                                              COMMUNICATOR_CONFIG_SECTION,
1837                                              "MAX_QUEUE_LENGTH",
1838                                              &max_queue_length))
1839     max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
1840
1841   in = udp_address_to_sockaddr (bindto,
1842                                 &in_len);
1843   if (NULL == in)
1844   {
1845     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1846                 "Failed to setup UDP socket address with path `%s'\n",
1847                 bindto);
1848     GNUNET_free (bindto);
1849     return;
1850   }
1851   udp_sock = GNUNET_NETWORK_socket_create (in->sa_family,
1852                                            SOCK_DGRAM,
1853                                            IPPROTO_UDP);
1854   if (NULL == udp_sock)
1855   {
1856     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1857                          "socket");
1858     GNUNET_free (in);
1859     GNUNET_free (bindto);
1860     return;
1861   }
1862   if (GNUNET_OK !=
1863       GNUNET_NETWORK_socket_bind (udp_sock,
1864                                   in,
1865                                   in_len))
1866   {
1867     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
1868                               "bind",
1869                               bindto);
1870     GNUNET_NETWORK_socket_close (udp_sock);
1871     listen_sock = NULL;
1872     GNUNET_free (in);
1873     GNUNET_free (bindto);
1874     return;
1875   }
1876   /* We might have bound to port 0, allowing the OS to figure it out;
1877      thus, get the real IN-address from the socket */
1878   sto_len = sizeof (in_sto);
1879   if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
1880                         (struct sockaddr *) &in_sto,
1881                         &sto_len))
1882   {
1883     memcpy (&in_sto,
1884             in,
1885             in_len);
1886     sto_len = in_len;
1887   }
1888   GNUNET_free (in);
1889   GNUNET_free (bindto);
1890   in = (struct sockaddr *) &in_sto;
1891   in_len = sto_len;
1892   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1893               "Bound to `%s'\n",
1894               GNUNET_a2s ((const struct sockaddr *) &in_sto,
1895                           sto_len));
1896   stats = GNUNET_STATISTICS_create ("C-UDP",
1897                                     cfg);
1898   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1899                                  NULL);
1900   is = GNUNET_NT_scanner_init ();
1901   my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
1902   if (NULL == my_private_key)
1903   {
1904     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1905                 _("Transport service is lacking key configuration settings. Exiting.\n"));
1906     GNUNET_SCHEDULER_shutdown ();
1907     return;
1908   }
1909   GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1910                                       &my_identity.public_key);
1911   /* start listening */
1912   read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1913                                              udp_sock,
1914                                              &sock_read,
1915                                              NULL);
1916   senders = GNUNET_CONTAINER_multipeermap_create (32,
1917                                                   GNUNET_YES);
1918   receivers = GNUNET_CONTAINER_multipeermap_create (32,
1919                                                     GNUNET_YES);
1920   key_cache = GNUNET_CONTAINER_multishortmap_create (1024,
1921                                                      GNUNET_YES);
1922   ch = GNUNET_TRANSPORT_communicator_connect (cfg,
1923                                               COMMUNICATOR_CONFIG_SECTION,
1924                                               COMMUNICATOR_ADDRESS_PREFIX,
1925                                               GNUNET_TRANSPORT_CC_UNRELIABLE,
1926                                               &mq_init,
1927                                               NULL,
1928                                               &enc_notify_cb,
1929                                               NULL);
1930   if (NULL == ch)
1931   {
1932     GNUNET_break (0);
1933     GNUNET_SCHEDULER_shutdown ();
1934     return;
1935   }
1936   nat = GNUNET_NAT_register (cfg,
1937                              COMMUNICATOR_CONFIG_SECTION,
1938                              IPPROTO_UDP,
1939                              1 /* one address */,
1940                              (const struct sockaddr **) &in,
1941                              &in_len,
1942                              &nat_address_cb,
1943                              NULL /* FIXME: support reversal: #5529 */,
1944                              NULL /* closure */);
1945 }
1946
1947
1948 /**
1949  * The main function for the UNIX communicator.
1950  *
1951  * @param argc number of arguments from the command line
1952  * @param argv command line arguments
1953  * @return 0 ok, 1 on error
1954  */
1955 int
1956 main (int argc,
1957       char *const *argv)
1958 {
1959   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1960     GNUNET_GETOPT_OPTION_END
1961   };
1962   int ret;
1963
1964   if (GNUNET_OK !=
1965       GNUNET_STRINGS_get_utf8_args (argc, argv,
1966                                     &argc, &argv))
1967     return 2;
1968
1969   ret =
1970       (GNUNET_OK ==
1971        GNUNET_PROGRAM_run (argc, argv,
1972                            "gnunet-communicator-udp",
1973                            _("GNUnet UDP communicator"),
1974                            options,
1975                            &run,
1976                            NULL)) ? 0 : 1;
1977   GNUNET_free ((void*) argv);
1978   return ret;
1979 }
1980
1981
1982 /* end of gnunet-communicator-udp.c */