gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] branch master updated: implement #5551 (UDP broadc


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated: implement #5551 (UDP broadcast learning in TNG)
Date: Sun, 07 Apr 2019 17:22:27 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 0142079ce implement #5551 (UDP broadcast learning in TNG)
0142079ce is described below

commit 0142079ce2e7a5e062d06aa8dddf2fdc1529035d
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun Apr 7 17:22:23 2019 +0200

    implement #5551 (UDP broadcast learning in TNG)
---
 src/include/gnunet_hello_lib.h                     |  18 +-
 src/include/gnunet_protocols.h                     |   7 +
 src/include/gnunet_transport_application_service.h |  46 +-
 src/nt/nt.c                                        |  24 +-
 src/transport/Makefile.am                          |   1 +
 src/transport/gnunet-communicator-udp.c            | 463 ++++++++++++---------
 src/transport/gnunet-service-tng.c                 | 106 +++--
 src/transport/transport.h                          |  31 ++
 src/transport/transport_api2_application.c         |  52 +++
 src/util/common_logging.c                          |  23 +-
 10 files changed, 479 insertions(+), 292 deletions(-)

diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
index fcd422701..5e2190cc6 100644
--- a/src/include/gnunet_hello_lib.h
+++ b/src/include/gnunet_hello_lib.h
@@ -495,11 +495,11 @@ GNUNET_HELLO_parse_uri (const char *uri,
  */
 void
 GNUNET_HELLO_sign_address (const char *address,
-                          enum GNUNET_NetworkType nt,
-                          struct GNUNET_TIME_Absolute expiration,
-                          const struct GNUNET_CRYPTO_EddsaPrivateKey 
*private_key,
-                          void **result,
-                          size_t *result_size);
+                           enum GNUNET_NetworkType nt,
+                           struct GNUNET_TIME_Absolute expiration,
+                           const struct GNUNET_CRYPTO_EddsaPrivateKey 
*private_key,
+                           void **result,
+                           size_t *result_size);
 
 
 /**
@@ -514,10 +514,10 @@ GNUNET_HELLO_sign_address (const char *address,
  */
 char *
 GNUNET_HELLO_extract_address (const void *raw,
-                             size_t raw_size,
-                             const struct GNUNET_PeerIdentity *pid,
-                             enum GNUNET_NetworkType *nt,
-                             struct GNUNET_TIME_Absolute *expiration);
+                              size_t raw_size,
+                              const struct GNUNET_PeerIdentity *pid,
+                              enum GNUNET_NetworkType *nt,
+                              struct GNUNET_TIME_Absolute *expiration);
 
 
 /**
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 7f1667d51..4f97d3078 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3189,8 +3189,15 @@ extern "C"
  */
 #define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL 1301
 
+/**
+ * Type of the 'struct RequestHelloValidationMessage' send by clients to 
TRANSPORT
+ * to trigger validation of addresses.
+ */
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION 1302
+
 
 /* ************** NEW (NG) ATS Messages ************* */
+/* NOTE: it is not clear ATS will survive in TNG      */
 
 /**
  * Type of the 'struct ExpressPreferenceMessage' send by clients to ATS
diff --git a/src/include/gnunet_transport_application_service.h 
b/src/include/gnunet_transport_application_service.h
index 31097b88e..bbd4e3ddf 100644
--- a/src/include/gnunet_transport_application_service.h
+++ b/src/include/gnunet_transport_application_service.h
@@ -34,6 +34,7 @@
 
 #include "gnunet_constants.h"
 #include "gnunet_util_lib.h"
+#include "gnunet_nt_lib.h"
 
 /**
  * Handle to the TRANSPORT subsystem for making suggestions about
@@ -62,37 +63,28 @@ GNUNET_TRANSPORT_application_done (struct 
GNUNET_TRANSPORT_ApplicationHandle *ch
 
 
 /**
- * Handle for suggestion requests.
- */
-struct GNUNET_TRANSPORT_ApplicationSuggestHandle;
-
-
-/**
- * An application would like to communicate with a peer.  TRANSPORT should
- * allocate bandwith using a suitable address for requiremetns @a pk
- * to transport.
+ * An application (or a communicator) has received a HELLO (or other address
+ * data of another peer) and wants TRANSPORT to validate that the address is
+ * correct.  The result is NOT returned, in fact TRANSPORT may do nothing
+ * (i.e. if it has too many active validations or recently tried this one
+ * already).  If the @a addr validates, TRANSPORT will persist the address
+ * with PEERSTORE.
  *
  * @param ch handle
- * @param peer identity of the peer we need an address for
- * @param pk what kind of application will the application require (can be
- *         #GNUNET_MQ_PREFERENCE_NONE, we will still try to connect)
- * @param bw desired bandwith, can be zero (we will still try to connect)
- * @return suggestion handle, NULL if request is already pending
- */
-struct GNUNET_TRANSPORT_ApplicationSuggestHandle *
-GNUNET_TRANSPORT_application_suggest (struct 
GNUNET_TRANSPORT_ApplicationHandle *ch,
-                                      const struct GNUNET_PeerIdentity *peer,
-                                      enum GNUNET_MQ_PreferenceKind pk,
-                                      struct GNUNET_BANDWIDTH_Value32NBO bw);
-
-
-/**
- * We no longer care about communicating with a peer.
- *
- * @param sh handle
+ * @param peer identity of the peer we have an address for
+ * @param expiration when does @a addr expire; used by TRANSPORT to know when
+ *        to definitively give up attempting to validate
+ * @param nt network type of @a addr (as claimed by the other peer);
+ *        used by TRANSPORT to avoid trying @a addr's that really cannot work
+ *        due to network type missmatches
+ * @param addr address to validate
  */
 void
-GNUNET_TRANSPORT_application_suggest_cancel (struct 
GNUNET_TRANSPORT_ApplicationSuggestHandle *sh);
+GNUNET_TRANSPORT_application_validate (struct 
GNUNET_TRANSPORT_ApplicationHandle *ch,
+                                       const struct GNUNET_PeerIdentity *peer,
+                                       struct GNUNET_TIME_Absolute expiration,
+                                       enum GNUNET_NetworkType nt,
+                                       const char *addr);
 
 /** @} */  /* end of group */
 
diff --git a/src/nt/nt.c b/src/nt/nt.c
index 3b95738e8..45d24520f 100644
--- a/src/nt/nt.c
+++ b/src/nt/nt.c
@@ -200,15 +200,21 @@ interface_proc (void *cls,
     net->netmask = (struct sockaddr *) &tmp[1];
     net->length = addrlen;
 
-    memset (&network4, 0, sizeof (network4));
+    memset (&network4,
+            0,
+            sizeof (network4));
     network4.sin_family = AF_INET;
 #if HAVE_SOCKADDR_IN_SIN_LEN
     network4.sin_len = sizeof (network4);
 #endif
     network4.sin_addr.s_addr = (addr4->sin_addr.s_addr & 
netmask4->sin_addr.s_addr);
 
-    GNUNET_memcpy (net->netmask, netmask4, sizeof (struct sockaddr_in));
-    GNUNET_memcpy (net->network, &network4, sizeof (struct sockaddr_in));
+    GNUNET_memcpy (net->netmask,
+                   netmask4,
+                   sizeof (struct sockaddr_in));
+    GNUNET_memcpy (net->network,
+                   &network4,
+                   sizeof (struct sockaddr_in));
   }
 
   if (addr->sa_family == AF_INET6)
@@ -236,8 +242,12 @@ interface_proc (void *cls,
     for (c = 0; c < 4; c++)
       net_elem[c] = addr_elem[c] & mask_elem[c];
 
-    GNUNET_memcpy (net->netmask, netmask6, sizeof (struct sockaddr_in6));
-    GNUNET_memcpy (net->network, &network6, sizeof (struct sockaddr_in6));
+    GNUNET_memcpy (net->netmask,
+                   netmask6,
+                   sizeof (struct sockaddr_in6));
+    GNUNET_memcpy (net->network,
+                   &network6,
+                   sizeof (struct sockaddr_in6));
   }
   if (NULL == net)
     return GNUNET_OK; /* odd / unsupported address family */
@@ -291,8 +301,8 @@ get_addresses (void *cls)
  */
 enum GNUNET_NetworkType
 GNUNET_NT_scanner_get_type (struct GNUNET_NT_InterfaceScanner *is,
-                           const struct sockaddr *addr,
-                           socklen_t addrlen)
+                            const struct sockaddr *addr,
+                            socklen_t addrlen)
 {
   struct NT_Network *cur = is->net_head;
   enum GNUNET_NetworkType type = GNUNET_NT_UNSPECIFIED;
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 2865460fd..f83fa669c 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -285,6 +285,7 @@ gnunet_communicator_tcp_LDADD = \
 gnunet_communicator_udp_SOURCES = \
  gnunet-communicator-udp.c
 gnunet_communicator_udp_LDADD = \
+  libgnunettransportapplication.la \
   libgnunettransportcommunicator.la \
   $(top_builddir)/src/nat/libgnunetnatnew.la \
   $(top_builddir)/src/nt/libgnunetnt.la \
diff --git a/src/transport/gnunet-communicator-udp.c 
b/src/transport/gnunet-communicator-udp.c
index fa8eb6acb..f101d2d75 100644
--- a/src/transport/gnunet-communicator-udp.c
+++ b/src/transport/gnunet-communicator-udp.c
@@ -35,7 +35,7 @@
  *    where is the API for that!?!)
  * - support DNS names in BINDTO option (#5528)
  * - support NAT connection reversal method (#5529)
- * - support other UDP-specific NAT traversal methods (#) 
+ * - support other UDP-specific NAT traversal methods (#)
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
@@ -45,26 +45,27 @@
 #include "gnunet_nt_lib.h"
 #include "gnunet_nat_service.h"
 #include "gnunet_statistics_service.h"
+#include "gnunet_transport_application_service.h"
 #include "gnunet_transport_communication_service.h"
 
 /**
  * How often do we rekey based on time (at least)
- */ 
+ */
 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
 
 /**
  * How long do we wait until we must have received the initial KX?
- */ 
+ */
 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
 
 /**
  * How often do we broadcast our presence on the LAN?
- */ 
+ */
 #define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
 
 /**
  * How often do we scan for changes to our network interfaces?
- */ 
+ */
 #define INTERFACE_SCAN_FREQUENCY GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MINUTES, 5)
 
 /**
@@ -88,7 +89,7 @@
  * #KCN_TARGET.
  * Should be large enough that we don't generate ACKs all
  * the time and still have enough time for the ACK to
- * arrive before the sender runs out. So really this 
+ * arrive before the sender runs out. So really this
  * should ideally be based on the RTT.
  */
 #define KCN_THRESHOLD 92
@@ -113,8 +114,8 @@
 #define MAX_SQN_DELTA 160
 
 /**
- * How many shared master secrets do we keep around 
- * at most per sender?  Should be large enough so 
+ * How many shared master secrets do we keep around
+ * at most per sender?  Should be large enough so
  * that we generally have a chance of sending an ACK
  * before the sender already rotated out the master
  * secret.  Generally values around #KCN_TARGET make
@@ -126,7 +127,7 @@
 /**
  * How often do we rekey based on number of bytes transmitted?
  * (additionally randomized).
- */ 
+ */
 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
 
 /**
@@ -157,23 +158,23 @@ struct UdpHandshakeSignature
 
   /**
    * Identity of the inititor of the UDP connection (UDP client).
-   */ 
+   */
   struct GNUNET_PeerIdentity sender;
 
   /**
    * Presumed identity of the target of the UDP connection (UDP server)
-   */ 
+   */
   struct GNUNET_PeerIdentity receiver;
 
   /**
    * Ephemeral key used by the @e sender.
-   */ 
+   */
   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
 
   /**
    * Monotonic time of @e sender, to possibly help detect replay attacks
    * (if receiver persists times by sender).
-   */ 
+   */
   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
 };
 
@@ -187,13 +188,13 @@ struct InitialKX
 
   /**
    * Ephemeral key for KX.
-   */ 
+   */
   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
 
   /**
    * HMAC for the following encrypted message, using GCM.  HMAC uses
    * key derived from the handshake with sequence number zero.
-   */ 
+   */
   char gcm_tag[GCM_TAG_SIZE];
 
 };
@@ -218,7 +219,7 @@ struct UDPConfirmation
   /**
    * Monotonic time of @e sender, to possibly help detect replay attacks
    * (if receiver persists times by sender).
-   */ 
+   */
   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
 
   /* followed by messages */
@@ -230,24 +231,24 @@ struct UDPConfirmation
 /**
  * UDP key acknowledgement.  May be sent via backchannel. Allows the
  * sender to use `struct UDPBox` with the acknowledge key henceforth.
- */ 
+ */
 struct UDPAck
 {
 
   /**
    * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
-   */ 
+   */
   struct GNUNET_MessageHeader header;
 
   /**
    * Sequence acknowledgement limit. Specifies current maximum sequence
    * number supported by receiver.
-   */ 
+   */
   uint32_t sequence_max GNUNET_PACKED;
-  
+
   /**
    * CMAC of the base key being acknowledged.
-   */ 
+   */
   struct GNUNET_HashCode cmac;
 
 };
@@ -257,7 +258,7 @@ struct UDPAck
  * Signature we use to verify that the broadcast was really made by
  * the peer that claims to have made it.  Basically, affirms that the
  * peer is really using this IP address (albeit possibly not in _our_
- * LAN).  Makes it difficult for peers in the LAN to claim to 
+ * LAN).  Makes it difficult for peers in the LAN to claim to
  * be just any global peer -- an attacker must have at least
  * shared a LAN with the peer they're pretending to be here.
  */
@@ -270,12 +271,12 @@ struct UdpBroadcastSignature
 
   /**
    * Identity of the inititor of the UDP broadcast.
-   */ 
+   */
   struct GNUNET_PeerIdentity sender;
 
   /**
    * Hash of the sender's UDP address.
-   */ 
+   */
   struct GNUNET_HashCode h_address;
 };
 
@@ -298,22 +299,22 @@ struct UDPBroadcast
    * Sender's signature of type
    * #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST
    */
-  struct GNUNET_CRYPTO_EddsaSignature sender_sig;  
-  
+  struct GNUNET_CRYPTO_EddsaSignature sender_sig;
+
 };
 
 
 /**
  * UDP message box.  Always sent encrypted, only allowed after
  * the receiver sent a `struct UDPAck` for the base key!
- */ 
+ */
 struct UDPBox
 {
 
   /**
    * Key and IV identification code. KDF applied to an acknowledged
    * base key and a sequence number.  Sequence numbers must be used
-   * monotonically increasing up to the maximum specified in 
+   * monotonically increasing up to the maximum specified in
    * `struct UDPAck`. Without further `struct UDPAck`s, the sender
    * must fall back to sending handshakes!
    */
@@ -325,9 +326,9 @@ struct UDPBox
    * extends until the end of the UDP payload.  If the @e hmac is
    * wrong, the receiver should check if the message might be a
    * `struct UdpHandshakeSignature`.
-   */ 
+   */
   char gcm_tag[GCM_TAG_SIZE];
-  
+
 };
 
 
@@ -350,7 +351,7 @@ struct KeyCacheEntry
    * Kept in a DLL.
    */
   struct KeyCacheEntry *next;
-  
+
   /**
    * Kept in a DLL.
    */
@@ -359,7 +360,7 @@ struct KeyCacheEntry
   /**
    * Key and IV identification code. KDF applied to an acknowledged
    * base key and a sequence number.  Sequence numbers must be used
-   * monotonically increasing up to the maximum specified in 
+   * monotonically increasing up to the maximum specified in
    * `struct UDPAck`. Without further `struct UDPAck`s, the sender
    * must fall back to sending handshakes!
    */
@@ -372,7 +373,7 @@ struct KeyCacheEntry
 
   /**
    * Sequence number used to derive this entry from master key.
-   */ 
+   */
   uint32_t sequence_number;
 };
 
@@ -408,7 +409,7 @@ struct SharedSecret
    * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
    */
   struct KeyCacheEntry *kce_head;
-  
+
   /**
    * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
    */
@@ -423,21 +424,21 @@ struct SharedSecret
    * Receiver we use this shared secret with, or NULL.
    */
   struct ReceiverAddress *receiver;
-  
+
   /**
    * Master shared secret.
-   */ 
+   */
   struct GNUNET_HashCode master;
 
   /**
    * CMAC is used to identify @e master in ACKs.
-   */ 
+   */
   struct GNUNET_HashCode cmac;
 
   /**
    * Up to which sequence number did we use this @e master already?
    * (for encrypting only)
-   */ 
+   */
   uint32_t sequence_used;
 
   /**
@@ -449,7 +450,7 @@ struct SharedSecret
 
   /**
    * Number of active KCN entries.
-   */ 
+   */
   unsigned int active_kce_count;
 };
 
@@ -464,11 +465,11 @@ struct SenderAddress
   /**
    * To whom are we talking to.
    */
-  struct GNUNET_PeerIdentity target;  
+  struct GNUNET_PeerIdentity target;
 
   /**
    * Entry in sender expiration heap.
-   */ 
+   */
   struct GNUNET_CONTAINER_HeapNode *hn;
 
   /**
@@ -480,12 +481,12 @@ struct SenderAddress
    * Shared secrets we used with @e target, last used is tail.
    */
   struct SharedSecret *ss_tail;
-  
+
   /**
    * Address of the other peer.
    */
   struct sockaddr *address;
-  
+
   /**
    * Length of the address.
    */
@@ -498,14 +499,14 @@ struct SenderAddress
 
   /**
    * Length of the DLL at @a ss_head.
-   */ 
+   */
   unsigned int num_secrets;
-  
+
   /**
    * Which network type does this queue use?
    */
   enum GNUNET_NetworkType nt;
-  
+
 };
 
 
@@ -519,8 +520,8 @@ struct ReceiverAddress
   /**
    * To whom are we talking to.
    */
-  struct GNUNET_PeerIdentity target;  
-  
+  struct GNUNET_PeerIdentity target;
+
   /**
    * Shared secrets we received from @e target, first used is head.
    */
@@ -534,14 +535,14 @@ struct ReceiverAddress
   /**
    * Address of the receiver in the human-readable format
    * with the #COMMUNICATOR_ADDRESS_PREFIX.
-   */ 
+   */
   char *foreign_addr;
 
   /**
    * Address of the other peer.
    */
   struct sockaddr *address;
-  
+
   /**
    * Length of the address.
    */
@@ -549,7 +550,7 @@ struct ReceiverAddress
 
   /**
    * Entry in sender expiration heap.
-   */ 
+   */
   struct GNUNET_CONTAINER_HeapNode *hn;
 
   /**
@@ -571,23 +572,23 @@ struct ReceiverAddress
    * MTU we allowed transport for this receiver right now.
    */
   size_t mtu;
-  
+
   /**
    * Length of the DLL at @a ss_head.
-   */ 
+   */
   unsigned int num_secrets;
 
   /**
-   * Number of BOX keys from ACKs we have currently 
+   * Number of BOX keys from ACKs we have currently
    * available for this receiver.
-   */ 
+   */
   unsigned int acks_available;
-  
+
   /**
    * Which network type does this queue use?
    */
   enum GNUNET_NetworkType nt;
-  
+
 };
 
 
@@ -611,12 +612,12 @@ struct BroadcastInterface
    * Task for this broadcast interface.
    */
   struct GNUNET_SCHEDULER_Task *broadcast_task;
-  
+
   /**
    * Sender's address of the interface.
    */
   struct sockaddr *sa;
-  
+
   /**
    * Broadcast address to use on the interface.
    */
@@ -624,18 +625,18 @@ struct BroadcastInterface
 
   /**
    * Message we broadcast on this interface.
-   */ 
+   */
   struct UDPBroadcast bcm;
-  
+
   /**
    * If this is an IPv6 interface, this is the request
    * we use to join/leave the group.
    */
   struct ipv6_mreq mcreq;
-  
+
   /**
    * Number of bytes in @e sa.
-   */ 
+   */
   socklen_t salen;
 
   /**
@@ -710,9 +711,9 @@ static struct BroadcastInterface *bi_tail;
  */
 static struct GNUNET_NETWORK_Handle *udp_sock;
 
-/** 
+/**
  * #GNUNET_YES if #udp_sock supports IPv6.
- */ 
+ */
 static int have_v6_socket;
 
 /**
@@ -730,6 +731,11 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey 
*my_private_key;
  */
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
+/**
+ * Our handle to report addresses for validation to TRANSPORT.
+ */
+static struct GNUNET_TRANSPORT_ApplicationHandle *ah;
+
 /**
  * Network scanner to determine network types.
  */
@@ -742,7 +748,7 @@ static struct GNUNET_NAT_Handle *nat;
 
 /**
  * Port number to which we are actually bound.
- */ 
+ */
 static uint16_t my_port;
 
 
@@ -788,7 +794,7 @@ static void
 receiver_destroy (struct ReceiverAddress *receiver)
 {
   struct GNUNET_MQ_Handle *mq;
-  
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Disconnecting receiver for peer `%s'\n",
              GNUNET_i2s (&receiver->target));
@@ -822,7 +828,7 @@ receiver_destroy (struct ReceiverAddress *receiver)
  * Free memory used by key cache entry.
  *
  * @param kce the key cache entry
- */ 
+ */
 static void
 kce_destroy (struct KeyCacheEntry *kce)
 {
@@ -1048,7 +1054,7 @@ check_timeouts (void *cls)
   struct GNUNET_TIME_Relative delay;
   struct ReceiverAddress *receiver;
   struct SenderAddress *sender;
-  
+
   (void) cls;
   timeout_task = NULL;
   rt = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1072,9 +1078,9 @@ check_timeouts (void *cls)
   if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
     timeout_task = GNUNET_SCHEDULER_add_delayed (delay,
                                                 &check_timeouts,
-                                                NULL);  
+                                                NULL);
 }
-                         
+
 
 /**
  * Calcualte cmac from master in @a ss.
@@ -1100,12 +1106,12 @@ calculate_cmac (struct SharedSecret *ss)
 
 /**
  * We received @a plaintext_len bytes of @a plaintext from a @a sender.
- * Pass it on to CORE.  
+ * Pass it on to CORE.
  *
  * @param queue the queue that received the plaintext
  * @param plaintext the plaintext that was received
  * @param plaintext_len number of bytes of plaintext received
- */ 
+ */
 static void
 pass_plaintext_to_core (struct SenderAddress *sender,
                        const void *plaintext,
@@ -1171,7 +1177,7 @@ setup_cipher (const struct GNUNET_HashCode *msec,
 
 
 /**
- * Try to decrypt @a buf using shared secret @a ss and key/iv 
+ * Try to decrypt @a buf using shared secret @a ss and key/iv
  * derived using @a serial.
  *
  * @param ss shared secret
@@ -1274,7 +1280,7 @@ setup_shared_secret_enc (const struct 
GNUNET_CRYPTO_EcdhePrivateKey *ephemeral,
  * recalculated and a fresh queue is initialized.
  *
  * @param receiver receiver to setup MQ for
- */ 
+ */
 static void
 setup_receiver_mq (struct ReceiverAddress *receiver);
 
@@ -1307,9 +1313,9 @@ handle_ack (void *cls,
                     sizeof (struct GNUNET_HashCode)))
     {
       uint32_t allowed;
-      
+
       allowed = ntohl (ack->sequence_max);
-                           
+
       if (allowed > ss->sequence_allowed)
       {
        receiver->acks_available += (allowed - ss->sequence_allowed);
@@ -1342,7 +1348,7 @@ handle_ack (void *cls,
  * @param sender peer to process inbound plaintext for
  * @param buf buffer we received
  * @param buf_size number of bytes in @a buf
- */ 
+ */
 static void
 try_handle_plaintext (struct SenderAddress *sender,
                      const void *buf,
@@ -1413,9 +1419,9 @@ consider_ss_ack (struct SharedSecret *ss)
     ack.sequence_max = htonl (ss->sequence_allowed);
     ack.cmac = ss->cmac;
     GNUNET_TRANSPORT_communicator_notify (ch,
-                                         &ss->sender->target,
-                                         COMMUNICATOR_ADDRESS_PREFIX,
-                                         &ack.header);
+                                          &ss->sender->target,
+                                          COMMUNICATOR_ADDRESS_PREFIX,
+                                          &ack.header);
   }
 }
 
@@ -1426,7 +1432,7 @@ consider_ss_ack (struct SharedSecret *ss)
  * @param box the data we received
  * @param box_len number of bytes in @a box
  * @param kce key index to decrypt @a box
- */ 
+ */
 static void
 decrypt_box (const struct UDPBox *box,
             size_t box_len,
@@ -1519,7 +1525,7 @@ find_sender_by_address (void *cls,
  * if one does not yet exist for @a address.
  *
  * @param target peer to generate address for
- * @param address target address 
+ * @param address target address
  * @param address_len number of bytes in @a address
  * @return data structure to keep track of key material for
  *         decrypting data from @a target
@@ -1582,10 +1588,10 @@ setup_sender (const struct GNUNET_PeerIdentity *target,
  */
 static int
 verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
-                    const struct UDPConfirmation *uc)
+                     const struct UDPConfirmation *uc)
 {
   struct UdpHandshakeSignature uhs;
-                       
+
   uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE);
   uhs.purpose.size = htonl (sizeof (uhs));
   uhs.sender = uc->sender;
@@ -1593,14 +1599,51 @@ verify_confirmation (const struct 
GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
   uhs.ephemeral = *ephemeral;
   uhs.monotonic_time = uc->monotonic_time;
   return GNUNET_CRYPTO_eddsa_verify 
(GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE,
-                                    &uhs.purpose,
-                                    &uc->sender_sig,
-                                    &uc->sender.public_key);
+                                     &uhs.purpose,
+                                     &uc->sender_sig,
+                                     &uc->sender.public_key);
+}
+
+
+/**
+ * Converts @a address to the address string format used by this
+ * communicator in HELLOs.
+ *
+ * @param address the address to convert, must be AF_INET or AF_INET6.
+ * @param address_len number of bytes in @a address
+ * @return string representation of @a address
+ */
+static char *
+sockaddr_to_udpaddr_string (const struct sockaddr *address,
+                            socklen_t address_len)
+{
+  char *ret;
+
+  switch (address->sa_family)
+  {
+  case AF_INET:
+    GNUNET_asprintf (&ret,
+                     "%s-%s",
+                     COMMUNICATOR_ADDRESS_PREFIX,
+                     GNUNET_a2s (address,
+                                 address_len));
+    break;
+  case AF_INET6:
+    GNUNET_asprintf (&ret,
+                     "%s-%s",
+                     COMMUNICATOR_ADDRESS_PREFIX,
+                     GNUNET_a2s (address,
+                                 address_len));
+    break;
+  default:
+    GNUNET_assert (0);
+  }
+  return ret;
 }
 
 
 /**
- * Socket read task. 
+ * Socket read task.
  *
  * @param cls NULL
  */
@@ -1615,18 +1658,18 @@ sock_read (void *cls)
   (void) cls;
   read_task
       = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
-                                      udp_sock,
-                                      &sock_read,
-                                      NULL);
+                                       udp_sock,
+                                       &sock_read,
+                                       NULL);
   rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
-                                        buf,
-                                        sizeof (buf),
-                                        (struct sockaddr *) &sa,
-                                        &salen);
+                                         buf,
+                                         sizeof (buf),
+                                         (struct sockaddr *) &sa,
+                                         &salen);
   if (-1 == rcvd)
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
-                        "recv");
+                         "recv");
     return;
   }
 
@@ -1638,12 +1681,12 @@ sock_read (void *cls)
 
     box = (const struct UDPBox *) buf;
     kce = GNUNET_CONTAINER_multishortmap_get (key_cache,
-                                             &box->kid);
+                                              &box->kid);
     if (NULL != kce)
     {
       decrypt_box (box,
-                  (size_t) rcvd,
-                  kce);
+                   (size_t) rcvd,
+                   kce);
       return;
     }
   }
@@ -1659,25 +1702,41 @@ sock_read (void *cls)
     uhs.purpose.size = htonl (sizeof (uhs));
     uhs.sender = ub->sender;
     GNUNET_CRYPTO_hash (&sa,
-                       salen,
-                       &uhs.h_address);
+                        salen,
+                        &uhs.h_address);
     if (GNUNET_OK ==
-       GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST,
-                                   &uhs.purpose,
-                                   &ub->sender_sig,
-                                   &ub->sender.public_key))
+        GNUNET_CRYPTO_eddsa_verify 
(GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST,
+                                    &uhs.purpose,
+                                    &ub->sender_sig,
+                                    &ub->sender.public_key))
     {
+      char *addr_s;
+      struct GNUNET_TIME_Absolute expiration;
+      enum GNUNET_NetworkType nt;
+
+      addr_s = sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa,
+                                           salen);
       GNUNET_STATISTICS_update (stats,
-                               "# broadcasts received",
-                               1,
-                               GNUNET_NO);
-      // FIXME #5551: we effectively just got a HELLO!
-      // trigger verification NOW!
+                                "# broadcasts received",
+                                1,
+                                GNUNET_NO);
+      /* expire at the broadcast frequency, as then we'll get the next one 
anyway */
+      expiration = GNUNET_TIME_relative_to_absolute (BROADCAST_FREQUENCY);
+      /* use our own mechanism to determine network type */
+      nt = GNUNET_NT_scanner_get_type (is,
+                                       (const struct sockaddr *) &sa,
+                                       salen);
+      GNUNET_TRANSPORT_application_validate (ah,
+                                             &ub->sender,
+                                             expiration,
+                                             nt,
+                                             addr_s);
+      GNUNET_free (addr_s);
       return;
     }
     /* continue with KX, mostly for statistics... */
   }
-  
+
 
   /* finally, test if it is a KX */
   if (rcvd < sizeof (struct UDPConfirmation) + sizeof (struct InitialKX))
@@ -1769,7 +1828,7 @@ udp_address_to_sockaddr (const char *bindto,
   char dummy[2];
   char *colon;
   char *cp;
-  
+
   if (1 == SSCANF (bindto,
                   "%u%1s",
                   &port,
@@ -1791,7 +1850,7 @@ udp_address_to_sockaddr (const char *bindto,
                                                "DISABLE_V6")) )
     {
       struct sockaddr_in *i4;
-      
+
       i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
       i4->sin_family = AF_INET;
       i4->sin_port = htons ((uint16_t) port);
@@ -1801,7 +1860,7 @@ udp_address_to_sockaddr (const char *bindto,
     else
     {
       struct sockaddr_in6 *i6;
-      
+
       i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
       i6->sin6_family = AF_INET6;
       i6->sin6_port = htons ((uint16_t) port);
@@ -1915,7 +1974,7 @@ do_pad (gcry_cipher_hd_t out_cipher,
       .size = htons (sizeof (pad)),
       .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD)
     };
-    
+
     memcpy (pad,
            &hdr,
            sizeof (hdr));
@@ -1953,7 +2012,7 @@ mq_send (struct GNUNET_MQ_Handle *mq,
     return;
   }
   reschedule_receiver_timeout (receiver);
-  
+
   if (0 == receiver->acks_available)
   {
     /* use KX encryption method */
@@ -2159,12 +2218,12 @@ mq_error (void *cls,
  * recalculated and a fresh queue is initialized.
  *
  * @param receiver receiver to setup MQ for
- */ 
+ */
 static void
 setup_receiver_mq (struct ReceiverAddress *receiver)
 {
   size_t base_mtu;
-  
+
   if (NULL != receiver->qh)
   {
     GNUNET_TRANSPORT_communicator_mq_del (receiver->qh);
@@ -2226,58 +2285,40 @@ setup_receiver_mq (struct ReceiverAddress *receiver)
 
 /**
  * Setup a receiver for transmission.  Setup the MQ processing and
- * inform transport that the queue is ready. 
+ * inform transport that the queue is ready.
  *
- * @param 
- */ 
+ * @param
+ */
 static struct ReceiverAddress *
 receiver_setup (const struct GNUNET_PeerIdentity *target,
-               const struct sockaddr *address,
-               socklen_t address_len)
+                const struct sockaddr *address,
+                socklen_t address_len)
 {
   struct ReceiverAddress *receiver;
 
   receiver = GNUNET_new (struct ReceiverAddress);
   receiver->address = GNUNET_memdup (address,
-                                    address_len);
+                                     address_len);
   receiver->address_len = address_len;
   receiver->target = *target;
   receiver->nt = GNUNET_NT_scanner_get_type (is,
                                             address,
                                             address_len);
   (void) GNUNET_CONTAINER_multipeermap_put (receivers,
-                                           &receiver->target,
-                                           receiver,
-                                           
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+                                            &receiver->target,
+                                            receiver,
+                                            
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
   receiver->timeout
     = GNUNET_TIME_relative_to_absolute 
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
   receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap,
-                                              receiver,
-                                              receiver->timeout.abs_value_us);
+                                               receiver,
+                                               receiver->timeout.abs_value_us);
   GNUNET_STATISTICS_set (stats,
-                        "# receivers active",
-                        GNUNET_CONTAINER_multipeermap_size (receivers),
-                        GNUNET_NO);
-  switch (address->sa_family)
-  {
-  case AF_INET:
-    GNUNET_asprintf (&receiver->foreign_addr,
-                    "%s-%s",
-                    COMMUNICATOR_ADDRESS_PREFIX,
-                    GNUNET_a2s (receiver->address,
-                                receiver->address_len));
-    break;
-  case AF_INET6:
-    GNUNET_asprintf (&receiver->foreign_addr,
-                    "%s-%s",
-                    COMMUNICATOR_ADDRESS_PREFIX,
-                    GNUNET_a2s (receiver->address,
-                                receiver->address_len));
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-
+                         "# receivers active",
+                         GNUNET_CONTAINER_multipeermap_size (receivers),
+                         GNUNET_NO);
+  receiver->foreign_addr = sockaddr_to_udpaddr_string (receiver->address,
+                                                       receiver->address_len);
   setup_receiver_mq (receiver);
 
   if (NULL == timeout_task)
@@ -2313,7 +2354,7 @@ mq_init (void *cls,
   const char *path;
   struct sockaddr *in;
   socklen_t in_len;
-  
+
   if (0 != strncmp (address,
                    COMMUNICATOR_ADDRESS_PREFIX "-",
                    strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
@@ -2323,12 +2364,12 @@ mq_init (void *cls,
   }
   path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
   in = udp_address_to_sockaddr (path,
-                               &in_len);  
+                               &in_len);
   receiver = receiver_setup (peer,
                             in,
                             in_len);
   (void) receiver;
-  return GNUNET_OK;  
+  return GNUNET_OK;
 }
 
 
@@ -2423,6 +2464,11 @@ do_shutdown (void *cls)
     GNUNET_TRANSPORT_communicator_disconnect (ch);
     ch = NULL;
   }
+  if (NULL != ah)
+  {
+    GNUNET_TRANSPORT_application_done (ah);
+    ah = NULL;
+  }
   if (NULL != stats)
   {
     GNUNET_STATISTICS_destroy (stats,
@@ -2457,7 +2503,7 @@ enc_notify_cb (void *cls,
                const struct GNUNET_MessageHeader *msg)
 {
   const struct UDPAck *ack;
-  
+
   (void) cls;
   if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) ||
        (ntohs (msg->size) != sizeof (struct UDPAck)) )
@@ -2480,7 +2526,7 @@ enc_notify_cb (void *cls,
  * @param cls closure
  * @param app_ctx[in,out] location where the app can store stuff
  *                  on add and retrieve it on remove
- * @param add_remove #GNUNET_YES to add a new public IP address, 
+ * @param add_remove #GNUNET_YES to add a new public IP address,
  *                   #GNUNET_NO to remove a previous (now invalid) one
  * @param ac address class the address belongs to
  * @param addr either the previous or the new public IP address
@@ -2502,13 +2548,13 @@ nat_address_cb (void *cls,
     enum GNUNET_NetworkType nt;
 
     GNUNET_asprintf (&my_addr,
-                    "%s-%s",
-                    COMMUNICATOR_ADDRESS_PREFIX,
-                    GNUNET_a2s (addr,
-                                addrlen));
+                     "%s-%s",
+                     COMMUNICATOR_ADDRESS_PREFIX,
+                     GNUNET_a2s (addr,
+                                 addrlen));
     nt = GNUNET_NT_scanner_get_type (is,
-                                    addr,
-                                    addrlen); 
+                                     addr,
+                                     addrlen);
     ai = GNUNET_TRANSPORT_communicator_address_add (ch,
                                                    my_addr,
                                                    nt,
@@ -2543,14 +2589,14 @@ ifc_broadcast (void *cls)
     = GNUNET_SCHEDULER_add_delayed (INTERFACE_SCAN_FREQUENCY,
                                    &ifc_broadcast,
                                    bi);
-  
+
   switch (bi->sa->sa_family) {
   case AF_INET:
     {
       static int yes = 1;
       static int no = 0;
       ssize_t sent;
-    
+
       if (GNUNET_OK !=
          GNUNET_NETWORK_socket_setsockopt (udp_sock,
                                            SOL_SOCKET,
@@ -2660,7 +2706,7 @@ iface_proc (void *cls,
   if ( (AF_INET6 == addr->sa_family) &&
        (GNUNET_YES != have_v6_socket) )
     return GNUNET_OK; /* not using IPv6 */
-  
+
   bi = GNUNET_new (struct BroadcastInterface);
   bi->sa = GNUNET_memdup (addr,
                          addrlen);
@@ -2696,7 +2742,7 @@ iface_proc (void *cls,
                    inet_pton (AF_INET6,
                              "FF05::13B",
                               &bi->mcreq.ipv6mr_multiaddr));
-    
+
     /* http://tools.ietf.org/html/rfc2553#section-5.2:
      *
      * IPV6_JOIN_GROUP
@@ -2736,7 +2782,7 @@ static void
 do_broadcast (void *cls)
 {
   struct BroadcastInterface *bin;
-  
+
   (void) cls;
   for (struct BroadcastInterface *bi = bi_head;
        NULL != bi;
@@ -2778,7 +2824,7 @@ run (void *cls,
   socklen_t in_len;
   struct sockaddr_storage in_sto;
   socklen_t sto_len;
-  
+
   (void) cls;
   cfg = c;
   if (GNUNET_OK !=
@@ -2794,7 +2840,7 @@ run (void *cls,
   }
 
   in = udp_address_to_sockaddr (bindto,
-                               &in_len);
+                                &in_len);
   if (NULL == in)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -2804,8 +2850,8 @@ run (void *cls,
     return;
   }
   udp_sock = GNUNET_NETWORK_socket_create (in->sa_family,
-                                          SOCK_DGRAM,
-                                          IPPROTO_UDP);
+                                           SOCK_DGRAM,
+                                           IPPROTO_UDP);
   if (NULL == udp_sock)
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
@@ -2819,7 +2865,7 @@ run (void *cls,
   if (GNUNET_OK !=
       GNUNET_NETWORK_socket_bind (udp_sock,
                                   in,
-                                 in_len))
+                                  in_len))
   {
     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                              "bind",
@@ -2834,12 +2880,12 @@ run (void *cls,
      thus, get the real IN-address from the socket */
   sto_len = sizeof (in_sto);
   if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
-                       (struct sockaddr *) &in_sto,
-                       &sto_len))
+                        (struct sockaddr *) &in_sto,
+                        &sto_len))
   {
     memcpy (&in_sto,
-           in,
-           in_len);
+            in,
+            in_len);
     sto_len = in_len;
   }
   GNUNET_free (in);
@@ -2847,9 +2893,9 @@ run (void *cls,
   in = (struct sockaddr *) &in_sto;
   in_len = sto_len;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Bound to `%s'\n",
-             GNUNET_a2s ((const struct sockaddr *) &in_sto,
-                         sto_len));
+              "Bound to `%s'\n",
+              GNUNET_a2s ((const struct sockaddr *) &in_sto,
+                          sto_len));
   switch (in->sa_family)
   {
   case AF_INET:
@@ -2863,17 +2909,17 @@ run (void *cls,
     my_port = 0;
   }
   stats = GNUNET_STATISTICS_create ("C-UDP",
-                                   cfg);
+                                    cfg);
   senders = GNUNET_CONTAINER_multipeermap_create (32,
-                                                 GNUNET_YES);
+                                                  GNUNET_YES);
   receivers = GNUNET_CONTAINER_multipeermap_create (32,
-                                                   GNUNET_YES);
+                                                    GNUNET_YES);
   senders_heap = GNUNET_CONTAINER_heap_create 
(GNUNET_CONTAINER_HEAP_ORDER_MIN);
   receivers_heap = GNUNET_CONTAINER_heap_create 
(GNUNET_CONTAINER_HEAP_ORDER_MIN);
   key_cache = GNUNET_CONTAINER_multishortmap_create (1024,
-                                                    GNUNET_YES);
+                                                     GNUNET_YES);
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
-                                NULL);
+                                 NULL);
   is = GNUNET_NT_scanner_init ();
   my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
   if (NULL == my_private_key)
@@ -2887,15 +2933,15 @@ run (void *cls,
                                       &my_identity.public_key);
   /* start reading */
   read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
-                                            udp_sock,
-                                            &sock_read,
-                                            NULL);
+                                             udp_sock,
+                                             &sock_read,
+                                             NULL);
   ch = GNUNET_TRANSPORT_communicator_connect (cfg,
-                                             COMMUNICATOR_CONFIG_SECTION,
-                                             COMMUNICATOR_ADDRESS_PREFIX,
+                                              COMMUNICATOR_CONFIG_SECTION,
+                                              COMMUNICATOR_ADDRESS_PREFIX,
                                               GNUNET_TRANSPORT_CC_UNRELIABLE,
-                                             &mq_init,
-                                             NULL,
+                                              &mq_init,
+                                              NULL,
                                               &enc_notify_cb,
                                               NULL);
   if (NULL == ch)
@@ -2904,24 +2950,31 @@ run (void *cls,
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
+  ah = GNUNET_TRANSPORT_application_init (cfg);
+  if (NULL == ah)
+  {
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
   /* start broadcasting */
   if (GNUNET_YES !=
       GNUNET_CONFIGURATION_get_value_yesno (cfg,
-                                           COMMUNICATOR_CONFIG_SECTION,
-                                           "DISABLE_BROADCAST"))
+                                            COMMUNICATOR_CONFIG_SECTION,
+                                            "DISABLE_BROADCAST"))
   {
     broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast,
-                                              NULL);
-  }  
+                                               NULL);
+  }
   nat = GNUNET_NAT_register (cfg,
-                            COMMUNICATOR_CONFIG_SECTION,
-                            IPPROTO_UDP,
-                            1 /* one address */,
-                            (const struct sockaddr **) &in,
-                            &in_len,
-                            &nat_address_cb,
-                            NULL /* FIXME: support reversal: #5529 */,
-                            NULL /* closure */);
+                             COMMUNICATOR_CONFIG_SECTION,
+                             IPPROTO_UDP,
+                             1 /* one address */,
+                             (const struct sockaddr **) &in,
+                             &in_len,
+                             &nat_address_cb,
+                             NULL /* FIXME: support reversal: #5529 */,
+                             NULL /* closure */);
 }
 
 
diff --git a/src/transport/gnunet-service-tng.c 
b/src/transport/gnunet-service-tng.c
index 6494a5dfd..b41168d82 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -35,17 +35,12 @@
  * Implement next:
  * - address validation: what is our plan here?
  *   #1 Peerstore only gets 'validated' addresses
- *   #2 transport needs another API to "trigger" validation!
- *      API may be used by core/application or communicators;
- *      => use yet another lib/MQ/connection?
- *   #3 transport should use validation to also establish
+ *   #2 transport should use validation to also establish
  *      effective flow control (for uni-directional transports!)
- *   #4 UDP broadcasting logic must be extended to use the new API
- *   #5 only validated addresses are selected for scheduling; that
+ *   #3 only validated addresses are selected for scheduling; that
  *      also ensures we know the RTT
- *   #6 to ensure flow control and RTT are OK, we always do the
+ *   #4 to ensure flow control and RTT are OK, we always do the
  *      'validation', even if address comes from PEERSTORE
- *   #7
  * - ACK handling / retransmission
  * - address verification
  * - track RTT, distance, loss, etc.
@@ -58,9 +53,6 @@
  * - backchannel message encryption & decryption
  * -
  *
- * Easy:
- * - figure out how to call XXX_suggestion_cb!
- *
  * Later:
  * - change transport-core API to provide proper flow control in both
  *   directions, allow multiple messages per peer simultaneously (tag
@@ -2612,8 +2604,8 @@ expire_ephemerals (void *cls)
       continue;
     }
     ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
-                                             &expire_ephemerals,
-                                             NULL);
+                                              &expire_ephemerals,
+                                              NULL);
     return;
   }
 }
@@ -2640,7 +2632,7 @@ lookup_ephemeral (const struct GNUNET_PeerIdentity *pid,
   struct EphemeralConfirmation ec;
 
   ece = GNUNET_CONTAINER_multipeermap_get (ephemeral_map,
-                                          pid);
+                                           pid);
   if ( (NULL != ece) &&
        (0 == GNUNET_TIME_absolute_get_remaining 
(ece->ephemeral_validity).rel_value_us) )
   {
@@ -2652,27 +2644,27 @@ lookup_ephemeral (const struct GNUNET_PeerIdentity *pid,
     ece = GNUNET_new (struct EphemeralCacheEntry);
     ece->target = *pid;
     ece->ephemeral_validity = GNUNET_TIME_absolute_add 
(GNUNET_TIME_absolute_get_monotonic (GST_cfg),
-                                                       EPHEMERAL_VALIDITY);
+                                                        EPHEMERAL_VALIDITY);
     GNUNET_assert (GNUNET_OK ==
-                  GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key));
+                   GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key));
     GNUNET_CRYPTO_ecdhe_key_get_public (&ece->private_key,
-                                       &ece->ephemeral_key);
+                                        &ece->ephemeral_key);
     ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
     ec.purpose.size = htonl (sizeof (ec));
     ec.target = *pid;
     ec.ephemeral_key = ece->ephemeral_key;
     GNUNET_assert (GNUNET_OK ==
-                  GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
-                                            &ec.purpose,
-                                            &ece->sender_sig));
+                   GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
+                                             &ec.purpose,
+                                             &ece->sender_sig));
     ece->hn = GNUNET_CONTAINER_heap_insert (ephemeral_heap,
                                            ece,
                                            
ece->ephemeral_validity.abs_value_us);
     GNUNET_assert (GNUNET_OK ==
-                  GNUNET_CONTAINER_multipeermap_put (ephemeral_map,
-                                                     &ece->target,
-                                                     ece,
-                                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+                   GNUNET_CONTAINER_multipeermap_put (ephemeral_map,
+                                                      &ece->target,
+                                                      ece,
+                                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
     if (NULL == ephemeral_task)
       ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
                                                &expire_ephemerals,
@@ -2733,27 +2725,27 @@ handle_communicator_backchannel (void *cls,
   // FIXME: setup 'iv'
 #if FIXME
   dh_key_derive (&private_key,
-                &cb->pid,
-                &enc->iv,
-                &key);
+                 &cb->pid,
+                 &enc->iv,
+                 &key);
 #endif
   ppay.ephemeral_validity = GNUNET_TIME_absolute_hton (ephemeral_validity);
   ppay.monotonic_time = GNUNET_TIME_absolute_hton 
(GNUNET_TIME_absolute_get_monotonic (GST_cfg));
   mpos = (char *) &enc[1];
 #if FIXME
   encrypt (key,
-          &ppay,
-          &mpos,
-          sizeof (ppay));
+           &ppay,
+           &mpos,
+           sizeof (ppay));
   encrypt (key,
-          &cb[1],
-          &mpos,
-          ntohs (cb->header.size) - sizeof (*cb));
+           &cb[1],
+           &mpos,
+           ntohs (cb->header.size) - sizeof (*cb));
   hmac (key,
-       &enc->hmac);
+        &enc->hmac);
 #endif
   route_message (&cb->pid,
-                &enc->header);
+                 &enc->header);
   GNUNET_SERVICE_client_continue (tc->client);
 }
 
@@ -4490,10 +4482,10 @@ suggest_to_connect (const struct GNUNET_PeerIdentity 
*pid,
   cqm->request_id = htonl (idgen++);
   cqm->receiver = *pid;
   memcpy (&cqm[1],
-         address,
-         alen);
+          address,
+          alen);
   GNUNET_MQ_send (tc->mq,
-                 env);
+                  env);
 }
 
 
@@ -4642,7 +4634,7 @@ handle_suggest (void *cls,
   pr->wc = GNUNET_PEERSTORE_watch (peerstore,
                                    "transport",
                                    &pr->pid,
-                                   "hello",
+                                   GNUNET_HELLO_PEERSTORE_KEY,
                                    &handle_hello,
                                    pr);
   GNUNET_SERVICE_client_continue (tc->client);
@@ -4737,6 +4729,38 @@ handle_address_consider_verify (void *cls,
 }
 
 
+/**
+ * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION
+ * messages.
+ *
+ * @param cls a `struct TransportClient *`
+ * @param m message to verify
+ * @return #GNUNET_OK on success
+ */
+static int
+check_request_hello_validation (void *cls,
+                                const struct RequestHelloValidationMessage *m)
+{
+  GNUNET_MQ_check_zero_termination (m);
+  return GNUNET_OK;
+}
+
+
+/**
+ * A client encountered an address of another peer. Consider validating it,
+ * and if validation succeeds, persist it to PEERSTORE.
+ *
+ * @param cls a `struct TransportClient *`
+ * @param m message to verify
+ */
+static void
+handle_request_hello_validation (void *cls,
+                                 const struct RequestHelloValidationMessage *m)
+{
+  // FIXME: implement validation!
+}
+
+
 /**
  * Free neighbour entry.
  *
@@ -4927,6 +4951,10 @@ GNUNET_SERVICE_MAIN
                           GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL,
                           struct ExpressPreferenceMessage,
                           NULL),
+ GNUNET_MQ_hd_var_size (request_hello_validation,
+                        GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION,
+                        struct RequestHelloValidationMessage,
+                        NULL),
  /* communication with core */
  GNUNET_MQ_hd_fixed_size (client_start,
                           GNUNET_MESSAGE_TYPE_TRANSPORT_START,
diff --git a/src/transport/transport.h b/src/transport/transport.h
index b231ea8ae..fe1044383 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -1139,6 +1139,37 @@ struct ExpressPreferenceMessage
 };
 
 
+/**
+ * We got an address of another peer, TRANSPORT service
+ * should validate it.  There is no response.
+ */
+struct RequestHelloValidationMessage
+{
+
+    /**
+   * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * What type of network does the other peer claim this is?
+   * A `enum GNUNET_NetworkType` in NBO.
+   */
+  uint32_t nt GNUNET_PACKED;
+
+  /**
+   * Peer to the address is presumably for.
+   */
+  struct GNUNET_PeerIdentity peer;
+
+  /**
+   * When does the address expire?
+   */
+  struct GNUNET_TIME_AbsoluteNBO expiration;
+
+  /* followed by 0-terminated address to validate */
+};
+
 #endif
 
 GNUNET_NETWORK_STRUCT_END
diff --git a/src/transport/transport_api2_application.c 
b/src/transport/transport_api2_application.c
index 325438e11..414a21fe4 100644
--- a/src/transport/transport_api2_application.c
+++ b/src/transport/transport_api2_application.c
@@ -363,4 +363,56 @@ GNUNET_TRANSPORT_application_suggest_cancel (struct 
GNUNET_TRANSPORT_Application
 }
 
 
+
+/**
+ * An application (or a communicator) has received a HELLO (or other address
+ * data of another peer) and wants TRANSPORT to validate that the address is
+ * correct.  The result is NOT returned, in fact TRANSPORT may do nothing
+ * (i.e. if it has too many active validations or recently tried this one
+ * already).  If the @a addr validates, TRANSPORT will persist the address
+ * with PEERSTORE.
+ *
+ * @param ch handle
+ * @param peer identity of the peer we have an address for
+ * @param expiration when does @a addr expire; used by TRANSPORT to know when
+ *        to definitively give up attempting to validate
+ * @param nt network type of @a addr (as claimed by the other peer);
+ *        used by TRANSPORT to avoid trying @a addr's that really cannot work
+ *        due to network type missmatches
+ * @param addr address to validate
+ */
+void
+GNUNET_TRANSPORT_application_validate (struct 
GNUNET_TRANSPORT_ApplicationHandle *ch,
+                                       const struct GNUNET_PeerIdentity *peer,
+                                       struct GNUNET_TIME_Absolute expiration,
+                                       enum GNUNET_NetworkType nt,
+                                       const char *addr)
+{
+  struct GNUNET_MQ_Envelope *ev;
+  struct RequestHelloValidationMessage *m;
+  size_t alen;
+
+  if (NULL == ch->mq)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Address validation for %s:%s skipped as transport is not 
connected\n",
+                GNUNET_i2s (peer),
+                addr);
+    return;
+  }
+  alen = strlen (addr) + 1;
+  ev = GNUNET_MQ_msg_extra (m,
+                            alen,
+                            
GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION);
+  m->peer = *peer;
+  m->expiration = GNUNET_TIME_absolute_hton (expiration);
+  m->nt = htonl ((uint32_t) nt);
+  memcpy (&m[1],
+          addr,
+          alen);
+  GNUNET_MQ_send (ch->mq,
+                  ev);
+}
+
+
 /* end of transport_api2_application.c */
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 60f0b2e8b..de30cab3a 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -1462,11 +1462,17 @@ GNUNET_a2s (const struct sockaddr *addr,
     if (addrlen != sizeof (struct sockaddr_in))
       return "<invalid v4 address>";
     v4 = (const struct sockaddr_in *) addr;
-    inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
+    inet_ntop (AF_INET,
+               &v4->sin_addr,
+               buf,
+               INET_ADDRSTRLEN);
     if (0 == ntohs (v4->sin_port))
       return buf;
     strcat (buf, ":");
-    GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v4->sin_port));
+    GNUNET_snprintf (b2,
+                     sizeof (b2),
+                     "%u",
+                     ntohs (v4->sin_port));
     strcat (buf, b2);
     return buf;
   case AF_INET6:
@@ -1474,12 +1480,19 @@ GNUNET_a2s (const struct sockaddr *addr,
       return "<invalid v4 address>";
     v6 = (const struct sockaddr_in6 *) addr;
     buf[0] = '[';
-    inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
+    inet_ntop (AF_INET6,
+               &v6->sin6_addr,
+               &buf[1],
+               INET6_ADDRSTRLEN);
     if (0 == ntohs (v6->sin6_port))
       return &buf[1];
     strcat (buf, "]:");
-    GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v6->sin6_port));
-    strcat (buf, b2);
+    GNUNET_snprintf (b2,
+                     sizeof (b2),
+                     "%u",
+                     ntohs (v6->sin6_port));
+    strcat (buf,
+            b2);
     return buf;
   case AF_UNIX:
     if (addrlen <= sizeof (sa_family_t))

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]