gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r34943 - in gnunet/src: ats include transport


From: gnunet
Subject: [GNUnet-SVN] r34943 - in gnunet/src: ats include transport
Date: Mon, 19 Jan 2015 02:08:03 +0100

Author: grothoff
Date: 2015-01-19 02:08:03 +0100 (Mon, 19 Jan 2015)
New Revision: 34943

Added:
   gnunet/src/transport/gnunet-service-transport_ats.c
   gnunet/src/transport/gnunet-service-transport_ats.h
Modified:
   gnunet/src/ats/ats_api_scheduling.c
   gnunet/src/include/gnunet_ats_service.h
   gnunet/src/transport/Makefile.am
   gnunet/src/transport/gnunet-service-transport.c
   gnunet/src/transport/gnunet-service-transport.h
   gnunet/src/transport/gnunet-service-transport_blacklist.h
   gnunet/src/transport/gnunet-service-transport_hello.h
   gnunet/src/transport/gnunet-service-transport_manipulation.c
   gnunet/src/transport/gnunet-service-transport_manipulation.h
   gnunet/src/transport/gnunet-service-transport_neighbours.c
   gnunet/src/transport/gnunet-service-transport_neighbours.h
   gnunet/src/transport/gnunet-service-transport_validation.c
Log:
-towards improved ATS API, adding return value with address record when adding 
address, adding new subsystem with peer-to-address map to transport; causes 
various new assertions to fail, but no major regression -- not finished

Modified: gnunet/src/ats/ats_api_scheduling.c
===================================================================
--- gnunet/src/ats/ats_api_scheduling.c 2015-01-19 01:05:57 UTC (rev 34942)
+++ gnunet/src/ats/ats_api_scheduling.c 2015-01-19 01:08:03 UTC (rev 34943)
@@ -48,7 +48,13 @@
  */
 struct GNUNET_ATS_AddressRecord
 {
+
   /**
+   * Scheduling handle this address record belongs to.
+   */
+  struct GNUNET_ATS_SchedulingHandle *sh;
+
+  /**
    * Address data.
    */
   struct GNUNET_HELLO_Address *address;
@@ -331,7 +337,7 @@
     off++;
     i++;
   }
-  if ( (NOT_FOUND != off) &&
+  if ( (NOT_FOUND != off % sh->session_array_size) &&
        (NULL == sh->session_array[off % sh->session_array_size]) )
     return off;
   i = sh->session_array_size;
@@ -1191,9 +1197,10 @@
  * @param session session handle, can be NULL
  * @param ats performance data for the address
  * @param ats_count number of performance records in @a ats
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ * @return handle to the address representation inside ATS, NULL
+ *         on error (i.e. ATS knows this exact address already)
  */
-int
+struct GNUNET_ATS_AddressRecord *
 GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
                         const struct GNUNET_HELLO_Address *address,
                         struct Session *session,
@@ -1209,7 +1216,7 @@
   {
     /* we need a valid address */
     GNUNET_break (0);
-    return GNUNET_SYSERR;
+    return NULL;
   }
   namelen = (NULL == address->transport_name)
     ? 0
@@ -1224,17 +1231,18 @@
   {
     /* address too large for us, this should not happen */
     GNUNET_break (0);
-    return GNUNET_SYSERR;
+    return NULL;
   }
 
   if (NOT_FOUND != find_session_id (sh, session, address))
   {
     /* Already existing, nothing todo, but this should not happen */
     GNUNET_break (0);
-    return GNUNET_SYSERR;
+    return NULL;
   }
   s = find_empty_session_slot (sh);
   ar = GNUNET_new (struct GNUNET_ATS_AddressRecord);
+  ar->sh = sh;
   ar->slot = s;
   ar->session = session;
   ar->address = GNUNET_HELLO_address_copy (address);
@@ -1244,7 +1252,7 @@
   memcpy (ar->ats, ats, ats_count * sizeof (struct GNUNET_ATS_Information));
   sh->session_array[s] = ar;
   send_add_address_message (sh, ar, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD);
-  return GNUNET_OK;
+  return ar;
 }
 
 
@@ -1256,33 +1264,17 @@
  * which case the call may be ignored or the information may be stored
  * for later use).  Update bandwidth assignments.
  *
- * FIXME: change API so we do not have to do the linear search!
- *
- * @param sh handle
- * @param address the address
+ * @param ar address record to update information for
  * @param session session handle, can be NULL
  * @param ats performance data for the address
  * @param ats_count number of performance records in @a ats
- * @return #GNUNET_YES on success, #GNUNET_NO if address or session are 
unknown,
- * #GNUNET_SYSERR on hard failure
  */
-int
-GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
-                           const struct GNUNET_HELLO_Address *address,
+void
+GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
                            struct Session *session,
                            const struct GNUNET_ATS_Information *ats,
                            uint32_t ats_count)
 {
-  uint32_t s;
-  struct GNUNET_ATS_AddressRecord *ar;
-
-  s = find_session_id (sh, session, address);
-  if (NOT_FOUND == s)
-  {
-    GNUNET_break (0);
-    return GNUNET_NO;
-  }
-  ar = sh->session_array[s];
   GNUNET_array_grow (ar->ats,
                      ar->ats_count,
                      ats_count);
@@ -1290,8 +1282,9 @@
           ats,
           ats_count * sizeof (struct GNUNET_ATS_Information));
   ar->session = session;
-  send_add_address_message (sh, ar, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
-  return GNUNET_YES;
+  send_add_address_message (ar->sh,
+                            ar,
+                            GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
 }
 
 
@@ -1384,7 +1377,7 @@
   s = find_session_id (sh, session, address);
   if (NOT_FOUND == s)
   {
-    GNUNET_break (0);
+    GNUNET_assert (0);
     return;
   }
   ar = sh->session_array[s];

Modified: gnunet/src/include/gnunet_ats_service.h
===================================================================
--- gnunet/src/include/gnunet_ats_service.h     2015-01-19 01:05:57 UTC (rev 
34942)
+++ gnunet/src/include/gnunet_ats_service.h     2015-01-19 01:08:03 UTC (rev 
34943)
@@ -421,7 +421,7 @@
 
 
 /**
- * Returns where the address is located: LAN or WAN or ...
+ * Returns where the address is located: loopback, LAN or WAN.
  *
  * @param sh the `struct GNUNET_ATS_SchedulingHandle` handle
  * @param addr address
@@ -449,6 +449,12 @@
 
 
 /**
+ * Handle used within ATS to track an address.
+ */
+struct GNUNET_ATS_AddressRecord;
+
+
+/**
  * We have a new address ATS should know. Addresses have to be added with this
  * function before they can be: updated, set in use and destroyed
  *
@@ -457,8 +463,11 @@
  * @param session session handle (if available)
  * @param ats performance data for the address
  * @param ats_count number of performance records in @a ats
+ * @return handle to the address representation inside ATS, NULL
+ *         on error (i.e. ATS knows this exact address already, or
+ *         address is invalid)
  */
-int
+struct GNUNET_ATS_AddressRecord *
 GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
                         const struct GNUNET_HELLO_Address *address,
                         struct Session *session,
@@ -470,20 +479,19 @@
  * We have updated performance statistics for a given address.  Note
  * that this function can be called for addresses that are currently
  * in use as well as addresses that are valid but not actively in use.
- * Furthermore, the peer may not even be connected to us right now (in
- * which case the call may be ignored or the information may be stored
- * for later use).  Update bandwidth assignments.
+ * Furthermore, the peer may not even be connected to us right now (@a
+ * session value of NULL used to signal disconnect, or somehow we
+ * otherwise got updated on @a ats information).  Based on the
+ * information provided, ATS may update bandwidth assignments and
+ * suggest to switch addresses.
  *
- * @param sh handle
- * @param address updated address
+ * @param ar address record to update information for
  * @param session session handle (if available)
  * @param ats performance data for the address
  * @param ats_count number of performance records in @a ats
- * @return #GNUNET_OK or #GNUNET_SYSERR
  */
-int
-GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
-                           const struct GNUNET_HELLO_Address *address,
+void
+GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
                            struct Session *session,
                            const struct GNUNET_ATS_Information *ats,
                            uint32_t ats_count);

Modified: gnunet/src/transport/Makefile.am
===================================================================
--- gnunet/src/transport/Makefile.am    2015-01-19 01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/Makefile.am    2015-01-19 01:08:03 UTC (rev 34943)
@@ -240,6 +240,7 @@
 
 gnunet_service_transport_SOURCES = \
  gnunet-service-transport.c gnunet-service-transport.h \
+ gnunet-service-transport_ats.h gnunet-service-transport_ats.c \
  gnunet-service-transport_blacklist.h gnunet-service-transport_blacklist.c \
  gnunet-service-transport_clients.h gnunet-service-transport_clients.c \
  gnunet-service-transport_hello.h gnunet-service-transport_hello.c \
@@ -980,6 +981,7 @@
 test_quota_compliance_http_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -988,6 +990,7 @@
 test_quota_compliance_http_asymmetric_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -996,6 +999,7 @@
 test_quota_compliance_https_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1004,6 +1008,7 @@
 test_quota_compliance_https_asymmetric_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1121,6 +1126,7 @@
 test_quota_compliance_tcp_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1129,6 +1135,7 @@
 test_quota_compliance_tcp_asymmetric_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1137,6 +1144,7 @@
 test_quota_compliance_udp_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1145,6 +1153,7 @@
 test_quota_compliance_unix_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1153,6 +1162,7 @@
 test_quota_compliance_unix_asymmetric_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1161,6 +1171,7 @@
 test_quota_compliance_wlan_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1169,6 +1180,7 @@
 test_quota_compliance_wlan_asymmetric_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1178,6 +1190,7 @@
  $(top_builddir)/src/nat/libgnunetnat.la \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 
@@ -1186,6 +1199,7 @@
 test_quota_compliance_bluetooth_asymmetric_LDADD = \
  libgnunettransport.la \
  $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  libgnunettransporttesting.la
 

Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c     2015-01-19 01:05:57 UTC 
(rev 34942)
+++ gnunet/src/transport/gnunet-service-transport.c     2015-01-19 01:08:03 UTC 
(rev 34943)
@@ -20,7 +20,7 @@
 
 /**
  * @file transport/gnunet-service-transport.c
- * @brief
+ * @brief main for gnunet-service-transport
  * @author Christian Grothoff
  */
 #include "platform.h"
@@ -31,6 +31,7 @@
 #include "gnunet_peerinfo_service.h"
 #include "gnunet_ats_service.h"
 #include "gnunet-service-transport.h"
+#include "gnunet-service-transport_ats.h"
 #include "gnunet-service-transport_blacklist.h"
 #include "gnunet-service-transport_clients.h"
 #include "gnunet-service-transport_hello.h"
@@ -71,19 +72,21 @@
   struct GNUNET_SCHEDULER_Task * task;
 };
 
+
 struct BlacklistCheckContext
 {
   struct BlacklistCheckContext *prev;
+
   struct BlacklistCheckContext *next;
 
-
   struct GST_BlacklistCheck *blc;
 
   struct GNUNET_HELLO_Address *address;
+
   struct Session *session;
+
   struct GNUNET_MessageHeader *msg;
-  struct GNUNET_ATS_Information *ats;
-  uint32_t ats_count;
+
 };
 
 /* globals */
@@ -143,7 +146,14 @@
  */
 static struct SessionKiller *sk_tail;
 
+/**
+ * FIXME
+ */
 struct BlacklistCheckContext *bc_head;
+
+/**
+ * FIXME
+ */
 struct BlacklistCheckContext *bc_tail;
 
 
@@ -172,7 +182,7 @@
     return;
 
   GST_neighbours_send (target, hello, ntohs (hello->size), hello_expiration,
-      NULL, NULL );
+                       NULL, NULL);
 }
 
 /**
@@ -193,15 +203,18 @@
  * We received some payload.  Prepare to pass it on to our clients.
  *
  * @param peer (claimed) identity of the other peer
- * @param address the address
- * @param session session used
+ * @param address address and (claimed) identity of the other peer
+ * @param session identifier used for this session (NULL for plugins
+ *                that do not offer bi-directional communication to the sender
+ *                using the same "connection")
  * @param message the message to process
  * @return how long the plugin should wait until receiving more data
  */
 static struct GNUNET_TIME_Relative
 process_payload (const struct GNUNET_PeerIdentity *peer,
-    const struct GNUNET_HELLO_Address *address, struct Session *session,
-    const struct GNUNET_MessageHeader *message)
+                 const struct GNUNET_HELLO_Address *address,
+                 struct Session *session,
+                 const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_TIME_Relative ret;
   int do_forward;
@@ -214,18 +227,18 @@
   ret = GST_neighbours_calculate_receive_delay (peer, msg_size, &do_forward);
   if (! GST_neighbours_test_connected (peer))
   {
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-        "Discarded %u bytes type %u payload from peer `%s'\n", msg_size,
-        ntohs (message->type), GNUNET_i2s (peer));
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Discarded %u bytes type %u payload from peer `%s'\n",
+                msg_size,
+                ntohs (message->type),
+                GNUNET_i2s (peer));
     GNUNET_STATISTICS_update (GST_stats, gettext_noop
-    ("# bytes payload discarded due to not connected peer"), msg_size,
-        GNUNET_NO);
+                              ("# bytes payload discarded due to not connected 
peer"),
+                              msg_size,
+                              GNUNET_NO);
     return ret;
   }
 
-  // FIXME: why is this call here?
-  GST_ats_add_address (address, session, NULL, 0);
-
   if (GNUNET_YES != do_forward)
     return ret;
   im = (struct InboundMessage *) buf;
@@ -237,6 +250,7 @@
   return ret;
 }
 
+
 /**
  * Task to asynchronously terminate a session.
  *
@@ -254,16 +268,25 @@
   GNUNET_free(sk);
 }
 
+
+/**
+ * FIXME.  Also, consider moving the "bc_*" logic into
+ * blacklist.h?
+ */
 static void
-cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, 
struct Session *session)
+cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address,
+                                 struct Session *session)
 {
   struct BlacklistCheckContext *blctx;
   struct BlacklistCheckContext *next;
+
   next = bc_head;
   for (blctx = next; NULL != blctx; blctx = next)
   {
     next = blctx->next;
-    if ((NULL != blctx->address) && (0 == 
GNUNET_HELLO_address_cmp(blctx->address, address)) && (blctx->session == 
session))
+    if ( (NULL != blctx->address) &&
+         (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) &&
+         (blctx->session == session))
     {
       GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
       if (NULL != blctx->blc)
@@ -273,12 +296,12 @@
       }
       GNUNET_HELLO_address_free (blctx->address);
       GNUNET_free_non_null (blctx->msg);
-      GNUNET_free_non_null (blctx->ats);
       GNUNET_free (blctx);
     }
   }
 }
 
+
 /**
  * Force plugin to terminate session due to communication
  * issue.
@@ -287,7 +310,8 @@
  * @param session session to termiante
  */
 static void
-kill_session (const char *plugin_name, struct Session *session)
+kill_session (const char *plugin_name,
+              struct Session *session)
 {
   struct GNUNET_TRANSPORT_PluginFunctions *plugin;
   struct SessionKiller *sk;
@@ -306,14 +330,15 @@
   sk->session = session;
   sk->plugin = plugin;
   sk->task = GNUNET_SCHEDULER_add_now (&kill_session_task, sk);
-  GNUNET_CONTAINER_DLL_insert(sk_head, sk_tail, sk);
+  GNUNET_CONTAINER_DLL_insert (sk_head,
+                               sk_tail,
+                               sk);
 }
 
 
-
 /**
  * Black list check result for try_connect call
- * If connection to the peer is allowed request adddress and
+ * If connection to the peer is allowed request adddress and ???
  *
  * @param cls blc_ctx bl context
  * @param peer the peer
@@ -321,7 +346,8 @@
  */
 static void
 connect_bl_check_cont (void *cls,
-    const struct GNUNET_PeerIdentity *peer, int result)
+                       const struct GNUNET_PeerIdentity *peer,
+                       int result)
 {
   struct BlacklistCheckContext *blctx = cls;
 
@@ -335,8 +361,9 @@
                 "Received SYN message from peer `%s' with `%s' %p\n",
                 GNUNET_i2s (peer), GST_plugins_a2s (blctx->address), 
blctx->session);
 
-    if (GNUNET_OK != GST_neighbours_handle_session_syn (blctx->msg,
-        &blctx->address->peer))
+    if (GNUNET_OK !=
+        GST_neighbours_handle_session_syn (blctx->msg,
+                                           &blctx->address->peer))
     {
       cancel_pending_blacklist_checks (blctx->address, blctx->session);
       kill_session (blctx->address->transport_name, blctx->session);
@@ -361,38 +388,6 @@
 
 
 /**
- * Black list check result for try_connect call
- * If connection to the peer is allowed request adddress and
- *
- * @param cls blc_ctx bl context
- * @param peer the peer
- * @param result the result
- */
-static void
-connect_transport_bl_check_cont (void *cls,
-    const struct GNUNET_PeerIdentity *peer, int result)
-{
-  struct BlacklistCheckContext *blctx = cls;
-
-  GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
-  blctx->blc = NULL;
-
-  if (GNUNET_OK == result)
-  {
-    /* Blacklist allows to speak to this transport */
-    GST_ats_add_address (blctx->address,
-                         blctx->session,
-                         blctx->ats, blctx->ats_count);
-  }
-
-  if (NULL != blctx->address)
-    GNUNET_HELLO_address_free (blctx->address);
-  GNUNET_free (blctx->msg);
-  GNUNET_free (blctx);
-}
-
-
-/**
  * Function called by the transport for each received message.
  *
  * @param cls closure, const char* with the name of the plugin we received the 
message from
@@ -426,7 +421,9 @@
       GNUNET_i2s (&address->peer));
 
   GNUNET_STATISTICS_update (GST_stats, gettext_noop
-  ("# bytes total received"), ntohs (message->size), GNUNET_NO);
+                            ("# bytes total received"),
+                            ntohs (message->size),
+                            GNUNET_NO);
   GST_neighbours_notify_data_recv (&address->peer, address, session, message);
 
   switch (type)
@@ -442,19 +439,23 @@
     }
     return ret;
   case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-        "Processing `%s' from `%s'\n", "PING", GST_plugins_a2s (address));
-    if (GNUNET_OK
-        != GST_validation_handle_ping (&address->peer, message, address, 
session))
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Processing `%s' from `%s'\n", "PING",
+                GST_plugins_a2s (address));
+    if (GNUNET_OK !=
+        GST_validation_handle_ping (&address->peer,
+                                    message,
+                                    address,
+                                    session))
     {
       cancel_pending_blacklist_checks (address, session);
       kill_session (plugin_name, session);
     }
     break;
   case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-        "Processing `%s' from `%s'\n", "PONG",
-        GST_plugins_a2s (address));
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+               "Processing `%s' from `%s'\n", "PONG",
+               GST_plugins_a2s (address));
     if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message))
     {
       GNUNET_break_op(0);
@@ -475,18 +476,6 @@
     {
       blctx->blc = blc;
     }
-
-    blctx = GNUNET_new (struct BlacklistCheckContext);
-    blctx->address = GNUNET_HELLO_address_copy (address);
-    blctx->session = session;
-    blctx->msg = GNUNET_malloc (ntohs(message->size));
-    memcpy (blctx->msg, message, ntohs(message->size));
-    GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx);
-    if (NULL != (blc = GST_blacklist_test_allowed (&address->peer,
-        address->transport_name, &connect_transport_bl_check_cont, blctx)))
-    {
-      blctx->blc = blc;
-    }
     break;
   case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK:
     if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message,
@@ -529,6 +518,7 @@
   return ret;
 }
 
+
 /**
  * Function that will be called for each address the transport
  * is aware that it might be reachable under.  Update our HELLO.
@@ -539,8 +529,9 @@
  * @param address the address to add or remove
  */
 static void
-plugin_env_address_change_notification (void *cls, int add_remove,
-    const struct GNUNET_HELLO_Address *address)
+plugin_env_address_change_notification (void *cls,
+                                        int add_remove,
+                                        const struct GNUNET_HELLO_Address 
*address)
 {
   static int addresses = 0;
   struct GNUNET_STATISTICS_Handle *cfg = GST_stats;
@@ -562,11 +553,12 @@
   }
 
   GNUNET_log(GNUNET_ERROR_TYPE_INFO,
-      "Transport now has %u addresses to communicate\n", addresses);
-
+             "Transport now has %u addresses to communicate\n",
+             addresses);
   GST_hello_modify_addresses (add_remove, address);
 }
 
+
 /**
  * Function that will be called whenever the plugin internally
  * cleans up a session pointer and hence the service needs to
@@ -581,8 +573,9 @@
  * @param session which session is being destoyed
  */
 static void
-plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address,
-    struct Session *session)
+plugin_env_session_end (void *cls,
+                        const struct GNUNET_HELLO_Address *address,
+                        struct Session *session)
 {
   struct SessionKiller *sk;
 
@@ -591,40 +584,30 @@
     GNUNET_break (0);
     return;
   }
-
   if (NULL == session)
   {
     GNUNET_break (0);
     return;
   }
+  GNUNET_assert (strlen (address->transport_name) > 0);
 
-  GNUNET_assert(strlen (address->transport_name) > 0);
-  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Session %p to peer `%s' ended \n",
-      session, GNUNET_i2s (&address->peer));
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Notification from plugin `%s' about terminated %s session %p 
from peer `%s' address `%s'\n",
+              address->transport_name,
+              GNUNET_HELLO_address_check_option (address,
+                                                 
GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session,
+              GNUNET_i2s (&address->peer),
+              GST_plugins_a2s (address));
 
-  GNUNET_log(GNUNET_ERROR_TYPE_INFO,
-      "Notification from plugin `%s' about terminated %s session %p from peer 
`%s' address `%s'\n",
-      address->transport_name,
-      GNUNET_HELLO_address_check_option (address,
-          GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session,
-      GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
-
   GST_neighbours_session_terminated (&address->peer, session);
-
-  GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-      "transport-ats", "Telling ATS to destroy session %p from peer %s\n",
-      session, GNUNET_i2s (&address->peer));
-
-  /* Tell ATS that session has ended */
-  GNUNET_ATS_address_destroyed (GST_ats, address, session);
-
+  GST_ats_del_session (address, session);
   cancel_pending_blacklist_checks (address, session);
 
   for (sk = sk_head; NULL != sk; sk = sk->next)
   {
     if (sk->session == session)
     {
-      GNUNET_CONTAINER_DLL_remove(sk_head, sk_tail, sk);
+      GNUNET_CONTAINER_DLL_remove (sk_head, sk_tail, sk);
       GNUNET_SCHEDULER_cancel (sk->task);
       GNUNET_free(sk);
       break;
@@ -632,6 +615,7 @@
   }
 }
 
+
 /**
  * Function that will be called to figure if an address is an loopback,
  * LAN, WAN etc. address
@@ -651,14 +635,6 @@
     GNUNET_break(0);
     return GNUNET_ATS_NET_UNSPECIFIED;
   }
-  if (((addr->sa_family != AF_INET) && (addrlen != sizeof(struct sockaddr_in)))
-      && ((addr->sa_family != AF_INET6)
-          && (addrlen != sizeof(struct sockaddr_in6)))
-      && (addr->sa_family != AF_UNIX))
-  {
-    GNUNET_break(0);
-    return GNUNET_ATS_NET_UNSPECIFIED;
-  }
   return GNUNET_ATS_address_get_type (GST_ats,
                                       addr,
                                       addrlen);
@@ -666,110 +642,6 @@
 
 
 /**
- * Notify ATS about the new address including the network this address is
- * located in.
- *
- * @param address the address
- * @param session the session
- * @param ats ats information
- * @param ats_count number of @a ats information
- */
-void
-GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
-                     struct Session *session,
-                     const struct GNUNET_ATS_Information *ats,
-                     uint32_t ats_count)
-{
-  struct GNUNET_TRANSPORT_PluginFunctions *papi;
-  struct GNUNET_ATS_Information ats2[ats_count + 1];
-  uint32_t net;
-
-  /* valid new address, let ATS know! */
-  if (NULL == address->transport_name)
-  {
-    GNUNET_break(0);
-    return;
-  }
-  if (NULL == (papi = GST_plugins_find (address->transport_name)))
-  {
-    /* we don't have the plugin for this address */
-    GNUNET_break(0);
-    return;
-  }
-
-  if (GNUNET_YES == GNUNET_ATS_session_known (GST_ats, address, session))
-  {
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-        "ATS already knows the address, not passing it on again\n");
-    return;
-  }
-
-  net = papi->get_network (papi->cls, session);
-  if (GNUNET_ATS_NET_UNSPECIFIED == net)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-        _("Could not obtain a valid network for `%s' %s (%s)\n"),
-        GNUNET_i2s (&address->peer), GST_plugins_a2s (address),
-        address->transport_name);
-    return;
-  }
-  ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
-  ats2[0].value = htonl (net);
-  memcpy (&ats2[1], ats, sizeof(struct GNUNET_ATS_Information) * ats_count);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Notifying ATS about peer `%s''s new address `%s' session %p in 
network %s\n",
-              GNUNET_i2s (&address->peer),
-              (0 == address->address_length)
-              ? "<inbound>"
-              : GST_plugins_a2s (address),
-              session,
-              GNUNET_ATS_print_network_type (net));
-  GNUNET_ATS_address_add (GST_ats, address, session,
-                          ats2, ats_count + 1);
-}
-
-
-/**
- * Notify ATS about property changes to an address
- *
- * @param peer the peer
- * @param address the address
- * @param session the session
- * @param ats performance information
- * @param ats_count number of elements in @a ats
- */
-void
-GST_ats_update_metrics (const struct GNUNET_PeerIdentity *peer,
-                        const struct GNUNET_HELLO_Address *address,
-                        struct Session *session,
-                        const struct GNUNET_ATS_Information *ats,
-                        uint32_t ats_count)
-{
-  struct GNUNET_ATS_Information *ats_new;
-
-  if (GNUNET_NO == GNUNET_ATS_session_known (GST_ats, address, session))
-    return;
-
-  /* Call to manipulation to manipulate ATS information */
-  ats_new = GST_manipulation_manipulate_metrics (peer, address, session, ats,
-      ats_count);
-  if (NULL == ats_new)
-  {
-    GNUNET_break(0);
-    return;
-  }
-  if (GNUNET_NO == GNUNET_ATS_address_update (GST_ats, address, session,
-        ats_new, ats_count))
-  {
-    GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
-        _("Address or session unknown: failed to update properties for peer 
`%s' plugin `%s' address `%s' session %p\n"),
-        GNUNET_i2s (peer), address->transport_name, GST_plugins_a2s (address),
-        session);
-  }
-  GNUNET_free(ats_new);
-}
-
-/**
  * Function that will be called to update metrics for an address
  *
  * @param cls closure
@@ -785,25 +657,16 @@
                            const struct GNUNET_ATS_Information *ats,
                            uint32_t ats_count)
 {
-  if ((NULL == ats) || (0 == ats_count))
-    return;
-  GNUNET_assert(NULL != GST_ats);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Updating metrics for peer `%s' address %s session %p\n",
-              GNUNET_i2s (&address->peer),
-              GST_plugins_a2s (address),
-              session);
-  GST_ats_update_metrics (&address->peer,
-                          address,
+  GST_ats_update_metrics (address,
                           session,
                           ats, ats_count);
 }
 
 
 /**
- * Black list check result for try_connect call
- * If connection to the peer is allowed request adddress and
+ * Black list check result from blacklist check triggered when a
+ * plugin gave us a new session in #plugin_env_session_start().  If
+ * connection to the peer is disallowed, kill the session.
  *
  * @param cls blc_ctx bl context
  * @param peer the peer
@@ -811,26 +674,23 @@
  */
 static void
 plugin_env_session_start_bl_check_cont (void *cls,
-    const struct GNUNET_PeerIdentity *peer, int result)
+                                        const struct GNUNET_PeerIdentity *peer,
+                                        int result)
 {
   struct BlacklistCheckContext *blctx = cls;
 
-  GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
+  GNUNET_CONTAINER_DLL_remove (bc_head,
+                               bc_tail,
+                               blctx);
   blctx->blc = NULL;
-
-  if (GNUNET_OK == result)
+  if (GNUNET_OK != result)
   {
-    GST_ats_add_address (blctx->address, blctx->session,
-        blctx->ats, blctx->ats_count);
+    cancel_pending_blacklist_checks (blctx->address,
+                                     blctx->session);
+    kill_session (blctx->address->transport_name,
+                  blctx->session);
   }
-  else
-  {
-    cancel_pending_blacklist_checks (blctx->address, blctx->session);
-    kill_session (blctx->address->transport_name, blctx->session);
-  }
-
   GNUNET_HELLO_address_free (blctx->address);
-  GNUNET_free_non_null (blctx->ats);
   GNUNET_free (blctx);
 }
 
@@ -846,14 +706,13 @@
  */
 static void
 plugin_env_session_start (void *cls,
-                          struct GNUNET_HELLO_Address *address,
+                          const struct GNUNET_HELLO_Address *address,
                           struct Session *session,
                           const struct GNUNET_ATS_Information *ats,
                           uint32_t ats_count)
 {
   struct BlacklistCheckContext *blctx;
   struct GST_BlacklistCheck *blc;
-  int c;
 
   if (NULL == address)
   {
@@ -865,31 +724,47 @@
     GNUNET_break(0);
     return;
   }
-  GNUNET_log(GNUNET_ERROR_TYPE_INFO,
-      "Notification from plugin `%s' about new %s session %p from peer `%s' 
address `%s'\n",
-      address->transport_name,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Notification from plugin `%s' about new %s session %p from peer 
`%s' address `%s'\n",
+              address->transport_name,
+              GNUNET_HELLO_address_check_option (address,
+                                                 
GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound",
+              session,
+              GNUNET_i2s (&address->peer),
+              GST_plugins_a2s (address));
+  if (GNUNET_YES ==
       GNUNET_HELLO_address_check_option (address,
-          GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound",
-      session, GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
-
+                                         GNUNET_HELLO_ADDRESS_INFO_INBOUND))
+  {
+    /* inbound is always new */
+    GST_ats_add_address (address,
+                         session,
+                         ats,
+                         ats_count);
+  }
+  else
+  {
+    /* outbound should already be known */
+    GST_ats_new_session (address,
+                         session);
+    GST_ats_update_metrics (address,
+                            session,
+                            ats,
+                            ats_count);
+  }
   /* Do blacklist check if communication with this peer is allowed */
   blctx = GNUNET_new (struct BlacklistCheckContext);
   blctx->address = GNUNET_HELLO_address_copy (address);
   blctx->session = session;
-  if (ats_count > 0)
+  GNUNET_CONTAINER_DLL_insert (bc_head,
+                               bc_tail,
+                               blctx);
+  if (NULL !=
+      (blc = GST_blacklist_test_allowed (&address->peer,
+                                         address->transport_name,
+                                         
&plugin_env_session_start_bl_check_cont,
+                                         blctx)))
   {
-    blctx->ats = GNUNET_malloc (ats_count * sizeof (struct 
GNUNET_ATS_Information));
-    for (c = 0; c < ats_count; c++)
-    {
-      blctx->ats[c].type = ats[c].type;
-      blctx->ats[c].value = ats[c].value;
-    }
-  }
-
-  GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx);
-  if (NULL != (blc = GST_blacklist_test_allowed (&address->peer, 
address->transport_name,
-        &plugin_env_session_start_bl_check_cont, blctx)))
-  {
     blctx->blc = blc;
   }
 }
@@ -927,9 +802,9 @@
   /* ATS tells me to disconnect from peer */
   if ((0 == bw_in) && (0 == bw_out))
   {
-    GNUNET_log(GNUNET_ERROR_TYPE_INFO,
-        "ATS tells me to disconnect from peer `%s'\n",
-        GNUNET_i2s (&address->peer));
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "ATS tells me to disconnect from peer `%s'\n",
+                GNUNET_i2s (&address->peer));
     GST_neighbours_force_disconnect (&address->peer);
     return;
   }
@@ -952,9 +827,9 @@
  */
 static void
 neighbours_connect_notification (void *cls,
-    const struct GNUNET_PeerIdentity *peer,
-    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
-    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
+                                 const struct GNUNET_PeerIdentity *peer,
+                                 struct GNUNET_BANDWIDTH_Value32NBO 
bandwidth_in,
+                                 struct GNUNET_BANDWIDTH_Value32NBO 
bandwidth_out)
 {
   size_t len = sizeof(struct ConnectInfoMessage);
   char buf[len] GNUNET_ALIGN;
@@ -962,8 +837,9 @@
 
   connections++;
   GNUNET_log(GNUNET_ERROR_TYPE_INFO,
-      "We are now connected to peer `%s' and %u peers in total\n",
-      GNUNET_i2s (peer), connections);
+             "We are now connected to peer `%s' and %u peers in total\n",
+             GNUNET_i2s (peer),
+             connections);
   connect_msg->header.size = htons (sizeof(buf));
   connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
   connect_msg->id = *peer;
@@ -988,8 +864,8 @@
 
   connections--;
   GNUNET_log(GNUNET_ERROR_TYPE_INFO,
-      "Peer `%s' disconnected and we are connected to %u peers\n",
-      GNUNET_i2s (peer), connections);
+             "Peer `%s' disconnected and we are connected to %u peers\n",
+             GNUNET_i2s (peer), connections);
 
   GST_manipulation_peer_disconnect (peer);
   disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage));
@@ -1021,12 +897,12 @@
                                  struct GNUNET_BANDWIDTH_Value32NBO 
bandwidth_in,
                                  struct GNUNET_BANDWIDTH_Value32NBO 
bandwidth_out)
 {
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-             "Notifying about change for peer `%s' with address `%s' in state 
`%s' timing out at %s\n",
-             GNUNET_i2s (peer),
-             (NULL != address) ? GST_plugins_a2s (address) : "<none>",
-             GNUNET_TRANSPORT_ps2s (state),
-             GNUNET_STRINGS_absolute_time_to_string (state_timeout));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Notifying about change for peer `%s' with address `%s' in state 
`%s' timing out at %s\n",
+              GNUNET_i2s (peer),
+              (NULL != address) ? GST_plugins_a2s (address) : "<none>",
+              GNUNET_TRANSPORT_ps2s (state),
+              GNUNET_STRINGS_absolute_time_to_string (state_timeout));
 
   GST_clients_broadcast_peer_notification (peer,
                                            address,
@@ -1043,12 +919,13 @@
  * @param tc task context (unused)
  */
 static void
-shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+shutdown_task (void *cls,
+               const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   GST_neighbours_stop ();
   GST_validation_stop ();
   GST_plugins_unload ();
-
+  GST_ats_done ();
   GNUNET_ATS_scheduling_done (GST_ats);
   GST_ats = NULL;
   GST_clients_stop ();
@@ -1083,8 +960,9 @@
  * @param c configuration to use
  */
 static void
-run (void *cls, struct GNUNET_SERVER_Handle *server,
-    const struct GNUNET_CONFIGURATION_Handle *c)
+run (void *cls,
+     struct GNUNET_SERVER_Handle *server,
+     const struct GNUNET_CONFIGURATION_Handle *c)
 {
   char *keyfile;
   struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
@@ -1121,15 +999,16 @@
   GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
   GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg);
   GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
-      &GST_my_identity.public_key);
+                                      &GST_my_identity.public_key);
   GNUNET_assert(NULL != GST_my_private_key);
 
   GNUNET_log(GNUNET_ERROR_TYPE_INFO,
              "My identity is `%4s'\n",
              GNUNET_i2s_full (&GST_my_identity));
 
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
-      NULL );
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+                                &shutdown_task,
+                                NULL);
   if (NULL == GST_peerinfo)
   {
     GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
@@ -1152,8 +1031,10 @@
   }
   max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport 
*/
 #endif
-  GNUNET_CONFIGURATION_get_value_number (GST_cfg, "transport", "MAX_FD",
-      &max_fd_cfg);
+  GNUNET_CONFIGURATION_get_value_number (GST_cfg,
+                                         "transport",
+                                         "MAX_FD",
+                                         &max_fd_cfg);
 
   if (max_fd_cfg > max_fd_rlimit)
     max_fd = max_fd_cfg;
@@ -1162,9 +1043,9 @@
   if (max_fd < DEFAULT_MAX_FDS)
     max_fd = DEFAULT_MAX_FDS;
 
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
-      "Limiting number of sockets to %u: validation %u, neighbors: %u\n",
-      max_fd, (max_fd / 3), (max_fd / 3) * 2);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Limiting number of sockets to %u: validation %u, neighbors: 
%u\n",
+             max_fd, (max_fd / 3), (max_fd / 3) * 2);
 
   friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology",
       "FRIENDS-ONLY");
@@ -1176,7 +1057,8 @@
   GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity);
   GST_ats = GNUNET_ATS_scheduling_init (GST_cfg,
                                         &ats_request_address_change,
-                                        NULL );
+                                        NULL);
+  GST_ats_init ();
   GST_manipulation_init (GST_cfg);
   GST_plugins_load (&GST_manipulation_recv,
                     &GST_neighbours_register_quota_notification,

Modified: gnunet/src/transport/gnunet-service-transport.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport.h     2015-01-19 01:05:57 UTC 
(rev 34942)
+++ gnunet/src/transport/gnunet-service-transport.h     2015-01-19 01:08:03 UTC 
(rev 34943)
@@ -28,6 +28,7 @@
 
 #include "gnunet_util_lib.h"
 #include "gnunet_statistics_service.h"
+#include "gnunet_ats_service.h"
 #include "gnunet_transport_service.h"
 
 #define VERBOSE_VALIDATION GNUNET_YES
@@ -85,52 +86,20 @@
  *
  * @param cls closure, const char* with the name of the plugin we received the 
message from
  * @param address address and (claimed) identity of the other peer
- * @param message the message, NULL if we only care about
- *                learning about the delay until we should receive again
  * @param session identifier used for this session (NULL for plugins
  *                that do not offer bi-directional communication to the sender
  *                using the same "connection")
+ * @param message the message, NULL if we only care about
+ *                learning about the delay until we should receive again
  * @return how long the plugin should wait until receiving more data
  *         (plugins that do not support this, can ignore the return value)
  */
 struct GNUNET_TIME_Relative
 GST_receive_callback (void *cls,
-    const struct GNUNET_HELLO_Address *address,
-    struct Session *session,
-    const struct GNUNET_MessageHeader *message);
+                      const struct GNUNET_HELLO_Address *address,
+                      struct Session *session,
+                      const struct GNUNET_MessageHeader *message);
 
 
-/**
- * Notify ATS about the new address including the network this address is
- * located in.
- *
- * @param address the address
- * @param session the session
- * @param ats ats information
- * @param ats_count number of @a ats information
- */
-void
-GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
-                     struct Session *session,
-                     const struct GNUNET_ATS_Information *ats,
-                     uint32_t ats_count);
-
-
-/**
- * Notify ATS about property changes to an address
- *
- * @param peer the peer
- * @param address the address
- * @param session the session
- * @param ats performance information
- * @param ats_count number of elements in @a ats
- */
-void
-GST_ats_update_metrics (const struct GNUNET_PeerIdentity *peer,
-                       const struct GNUNET_HELLO_Address *address,
-                       struct Session *session,
-                       const struct GNUNET_ATS_Information *ats,
-                       uint32_t ats_count);
-
 #endif
 /* end of file gnunet-service-transport_plugins.h */

Added: gnunet/src/transport/gnunet-service-transport_ats.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_ats.c                         
(rev 0)
+++ gnunet/src/transport/gnunet-service-transport_ats.c 2015-01-19 01:08:03 UTC 
(rev 34943)
@@ -0,0 +1,441 @@
+/*
+     This file is part of GNUnet.
+     (C) 2015 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file transport/gnunet-service-transport_ats.h
+ * @brief interfacing between transport and ATS service
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet-service-transport.h"
+#include "gnunet-service-transport_ats.h"
+#include "gnunet-service-transport_manipulation.h"
+#include "gnunet-service-transport_plugins.h"
+#include "gnunet_ats_service.h"
+
+
+/**
+ * Information we track for each address known to ATS.
+ */
+struct AddressInfo
+{
+
+  /**
+   * The address (with peer identity).
+   */
+  struct GNUNET_HELLO_Address *address;
+
+  /**
+   * Session (can be NULL)
+   */
+  struct Session *session;
+
+  /**
+   * Record with ATS API for the address.
+   */
+  struct GNUNET_ATS_AddressRecord *ar;
+};
+
+
+/**
+ * Map from peer identities to one or more `struct AddressInfo` values
+ * for the peer.
+ */
+static struct GNUNET_CONTAINER_MultiPeerMap *p2a;
+
+
+/**
+ * Closure for #find_ai().
+ */
+struct FindClosure
+{
+
+  /**
+   * Session to look for (only used if the address is inbound).
+   */
+  struct Session *session;
+
+  /**
+   * Address to look for.
+   */
+  const struct GNUNET_HELLO_Address *address;
+
+  /**
+   * Where to store the result.
+   */
+  struct AddressInfo *ret;
+
+};
+
+
+/**
+ * Find matching address info.
+ *
+ * @param cls the `struct FindClosure`
+ * @param key which peer is this about
+ * @param value the `struct AddressInfo`
+ * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value
+ */
+static int
+find_ai_cb (void *cls,
+            const struct GNUNET_PeerIdentity *key,
+            void *value)
+{
+  struct FindClosure *fc = cls;
+  struct AddressInfo *ai = value;
+
+  if ( (0 ==
+        GNUNET_HELLO_address_cmp (fc->address,
+                                  ai->address) ) &&
+       (fc->session == ai->session) )
+  {
+    fc->ret = ai;
+    return GNUNET_NO;
+  }
+  return GNUNET_YES;
+}
+
+
+/**
+ * Find the address information struct for the
+ * given address and session.
+ *
+ * @param address address to look for
+ * @param session session to match for inbound connections
+ * @return NULL if this combination is unknown
+ */
+static struct AddressInfo *
+find_ai (const struct GNUNET_HELLO_Address *address,
+         struct Session *session)
+{
+  struct FindClosure fc;
+
+  fc.address = address;
+  fc.session = session;
+  fc.ret = NULL;
+  GNUNET_CONTAINER_multipeermap_get_multiple (p2a,
+                                              &address->peer,
+                                              &find_ai_cb,
+                                              &fc);
+  return fc.ret;
+}
+
+
+/**
+ * Notify ATS about the new address including the network this address is
+ * located in.
+ *
+ * @param address the address
+ * @param session the session
+ * @param ats ats information
+ * @param ats_count number of @a ats information
+ */
+void
+GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
+                     struct Session *session,
+                     const struct GNUNET_ATS_Information *ats,
+                     uint32_t ats_count)
+{
+  struct GNUNET_TRANSPORT_PluginFunctions *papi;
+  struct GNUNET_ATS_Information ats2[ats_count + 1];
+  struct GNUNET_ATS_AddressRecord *ar;
+  struct AddressInfo *ai;
+  uint32_t net;
+
+  /* valid new address, let ATS know! */
+  if (NULL == address->transport_name)
+  {
+    GNUNET_break(0);
+    return;
+  }
+  if (GNUNET_YES ==
+      GNUNET_HELLO_address_check_option (address,
+                                         GNUNET_HELLO_ADDRESS_INFO_INBOUND))
+  {
+    GNUNET_break (NULL != session);
+  }
+  else
+  {
+    GNUNET_break (NULL == session);
+  }
+  ai = find_ai (address, session);
+  if (NULL != ai)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  if (NULL == (papi = GST_plugins_find (address->transport_name)))
+  {
+    /* we don't have the plugin for this address */
+    GNUNET_break(0);
+    return;
+  }
+  if (NULL != session)
+  {
+    net = papi->get_network (papi->cls, session);
+    if (GNUNET_ATS_NET_UNSPECIFIED == net)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _ ("Could not obtain a valid network for `%s' %s (%s)\n"),
+                  GNUNET_i2s (&address->peer),
+                  GST_plugins_a2s (address),
+                  address->transport_name);
+      return;
+    }
+    ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+    ats2[0].value = htonl (net);
+    memcpy (&ats2[1],
+            ats,
+            sizeof(struct GNUNET_ATS_Information) * ats_count);
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Notifying ATS about peer `%s''s new address `%s' session %p in 
network %s\n",
+              GNUNET_i2s (&address->peer),
+              (0 == address->address_length)
+              ? "<inbound>"
+              : GST_plugins_a2s (address),
+              session,
+              GNUNET_ATS_print_network_type (net));
+  ar = GNUNET_ATS_address_add (GST_ats,
+                               address,
+                               session,
+                               (NULL != session) ? ats2 : ats,
+                               (NULL != session) ? ats_count + 1 : ats_count);
+  ai = GNUNET_new (struct AddressInfo);
+  ai->address = GNUNET_HELLO_address_copy (address);
+  ai->session = session;
+  ai->ar = ar;
+  (void) GNUNET_CONTAINER_multipeermap_put (p2a,
+                                            &ai->address->peer,
+                                            ai,
+                                            
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+}
+
+
+/**
+ * Notify ATS about a new session now existing for the given
+ * address.
+ *
+ * @param address the address
+ * @param session the session
+ */
+void
+GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
+                     struct Session *session)
+{
+  struct AddressInfo *ai;
+
+  ai = find_ai (address, NULL);
+  if (NULL == ai)
+  {
+    GNUNET_break (NULL != (find_ai (address, session)));
+    return;
+  }
+  GNUNET_break (NULL == ai->session);
+  ai->session = session;
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+                   "transport-ats",
+                   "Telling ATS about new session %p for peer %s\n",
+                   session,
+                   GNUNET_i2s (&address->peer));
+  // FIXME: tell ATS API, but not using this call:
+  GNUNET_ATS_address_update (ai->ar,
+                             session,
+                             NULL, 0);
+
+}
+
+
+/**
+ * Notify ATS that the session (but not the address) of
+ * a given address is no longer relevant.
+ *
+ * @param address the address
+ * @param session the session
+ */
+void
+GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
+                     struct Session *session)
+{
+  struct AddressInfo *ai;
+
+  if (NULL == session)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  ai = find_ai (address, session);
+  if (NULL == ai)
+  {
+    /* We sometimes create sessions just for sending a PING,
+       and if those are destroyed they were never known to
+       ATS which means we end up here (however, in this
+       case, the address must be an outbound address). */
+    GNUNET_break (GNUNET_YES !=
+                  GNUNET_HELLO_address_check_option (address,
+                                                     
GNUNET_HELLO_ADDRESS_INFO_INBOUND));
+
+    return;
+  }
+  GNUNET_assert (session == ai->session);
+  ai->session = NULL;
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+                   "transport-ats",
+                   "Telling ATS to destroy session %p from peer %s\n",
+                   session,
+                   GNUNET_i2s (&address->peer));
+  /* FIXME: if this was an *inbound* address, destroy it
+     FULLY here well; but use different API, as looking up
+     inbound address without session is not great... */
+  GNUNET_ATS_address_destroyed (GST_ats, address, session);
+  if (GNUNET_YES ==
+      GNUNET_HELLO_address_check_option (address,
+                                         GNUNET_HELLO_ADDRESS_INFO_INBOUND))
+    GST_ats_expire_address (address);
+}
+
+
+/**
+ * Notify ATS about property changes to an address.
+ *
+ * @param address our information about the address
+ * @param session the session
+ * @param ats performance information
+ * @param ats_count number of elements in @a ats
+ */
+void
+GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address,
+                        struct Session *session,
+                        const struct GNUNET_ATS_Information *ats,
+                        uint32_t ats_count)
+{
+  struct GNUNET_ATS_Information *ats_new;
+  struct AddressInfo *ai;
+
+  ai = find_ai (address, session);
+  if (NULL == ai)
+  {
+    /* We sometimes create sessions just for sending a PING,
+       and if we get metrics for those, they were never known to
+       ATS which means we end up here (however, in this
+       case, the address must be an outbound address). */
+    GNUNET_break (GNUNET_YES !=
+                  GNUNET_HELLO_address_check_option (address,
+                                                     
GNUNET_HELLO_ADDRESS_INFO_INBOUND));
+
+    return;
+  }
+  /* Call to manipulation to manipulate ATS information */
+  GNUNET_assert (NULL != GST_ats);
+  if ((NULL == ats) || (0 == ats_count))
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Updating metrics for peer `%s' address %s session %p\n",
+              GNUNET_i2s (&address->peer),
+              GST_plugins_a2s (address),
+              session);
+  ats_new = GST_manipulation_manipulate_metrics (address,
+                                                 session,
+                                                 ats,
+                                                 ats_count);
+  GNUNET_ATS_address_update (ai->ar,
+                             session,
+                             ats_new, ats_count);
+  GNUNET_free_non_null (ats_new);
+}
+
+
+/**
+ * Notify ATS that the address has expired and thus cannot
+ * be used any longer.  This function must only be called
+ * if the corresponding session is already gone.
+ *
+ * @param address the address
+ */
+void
+GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
+{
+  struct AddressInfo *ai;
+
+  ai = find_ai (address, NULL);
+  if (NULL == ai)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  GNUNET_assert (GNUNET_YES ==
+                 GNUNET_CONTAINER_multipeermap_remove (p2a,
+                                                       &address->peer,
+                                                       ai));
+  GNUNET_break (NULL == ai->session);
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+                   "transport-ats",
+                   "Telling ATS to destroy address from peer %s\n",
+                   GNUNET_i2s (&address->peer));
+  GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
+  GNUNET_HELLO_address_free (ai->address);
+  GNUNET_free (ai);
+}
+
+
+/**
+ * Initialize ATS subsystem.
+ */
+void
+GST_ats_init ()
+{
+  p2a = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_YES);
+}
+
+
+/**
+ * Release memory used by the given address data.
+ *
+ * @param cls NULL
+ * @param key which peer is this about
+ * @param value the `struct AddressInfo`
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static int
+destroy_ai (void *cls,
+            const struct GNUNET_PeerIdentity *key,
+            void *value)
+{
+  struct AddressInfo *ai = value;
+
+  GNUNET_HELLO_address_free (ai->address);
+  GNUNET_free (ai);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Shutdown ATS subsystem.
+ */
+void
+GST_ats_done ()
+{
+  GNUNET_CONTAINER_multipeermap_iterate (p2a,
+                                         &destroy_ai,
+                                         NULL);
+  GNUNET_CONTAINER_multipeermap_destroy (p2a);
+  p2a = NULL;
+}
+
+/* end of gnunet-service-transport_ats.c */

Added: gnunet/src/transport/gnunet-service-transport_ats.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport_ats.h                         
(rev 0)
+++ gnunet/src/transport/gnunet-service-transport_ats.h 2015-01-19 01:08:03 UTC 
(rev 34943)
@@ -0,0 +1,119 @@
+/*
+     This file is part of GNUnet.
+     (C) 2015 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file transport/gnunet-service-transport_ats.h
+ * @brief interfacing between transport and ATS service
+ * @author Christian Grothoff
+ *
+ * FIXME:
+ * - add API to give ATS feedback about an address that was
+ *   suggested but did not work out (without fully 'deleting'
+ *   it forever)
+ * - improve ATS API to take advantage of this new subsystem
+ *   when calling ATS functions, make ATS API match this API
+ *   more closely
+ * - combine with API to tell ATS about address "use"
+ */
+#ifndef GNUNET_SERVICE_TRANSPORT_ATS_H
+#define GNUNET_SERVICE_TRANSPORT_ATS_H
+
+#include "gnunet_ats_service.h"
+
+/**
+ * Initialize ATS subsystem.
+ */
+void
+GST_ats_init (void);
+
+
+/**
+ * Shutdown ATS subsystem.
+ */
+void
+GST_ats_done (void);
+
+
+/**
+ * Notify ATS about the new address including the network this address is
+ * located in.
+ *
+ * @param address the address
+ * @param session the session
+ * @param ats ats information
+ * @param ats_count number of @a ats information
+ */
+void
+GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
+                     struct Session *session,
+                     const struct GNUNET_ATS_Information *ats,
+                     uint32_t ats_count);
+
+
+/**
+ * Notify ATS about a new session now existing for the given
+ * address.
+ *
+ * @param address the address
+ * @param session the session
+ */
+void
+GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
+                     struct Session *session);
+
+
+/**
+ * Notify ATS about property changes to an address
+ *
+ * @param address the address
+ * @param session the session
+ * @param ats performance information
+ * @param ats_count number of elements in @a ats
+ */
+void
+GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address,
+                       struct Session *session,
+                       const struct GNUNET_ATS_Information *ats,
+                       uint32_t ats_count);
+
+
+/**
+ * Notify ATS that the session (but not the address) of
+ * a given address is no longer relevant.
+ *
+ * @param address the address
+ * @param session the session
+ */
+void
+GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
+                     struct Session *session);
+
+
+/**
+ * Notify ATS that the address has expired and thus cannot
+ * be used any longer.  This function must only be called
+ * if the corresponding session is already gone.
+ *
+ * @param address the address
+ */
+void
+GST_ats_expire_address (const struct GNUNET_HELLO_Address *address);
+
+
+#endif

Modified: gnunet/src/transport/gnunet-service-transport_blacklist.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport_blacklist.h   2015-01-19 
01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/gnunet-service-transport_blacklist.h   2015-01-19 
01:08:03 UTC (rev 34943)
@@ -38,8 +38,8 @@
  */
 void
 GST_blacklist_start (struct GNUNET_SERVER_Handle *server,
-                                                                               
 const struct GNUNET_CONFIGURATION_Handle *cfg,
-                                                                               
 const struct GNUNET_PeerIdentity *my_id);
+                     const struct GNUNET_CONFIGURATION_Handle *cfg,
+                     const struct GNUNET_PeerIdentity *my_id);
 
 
 /**
@@ -59,7 +59,8 @@
  * @param message the blacklist-init message that was sent
  */
 void
-GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client,
+GST_blacklist_handle_init (void *cls,
+                           struct GNUNET_SERVER_Client *client,
                            const struct GNUNET_MessageHeader *message);
 
 
@@ -71,7 +72,8 @@
  * @param message the blacklist-init message that was sent
  */
 void
-GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client,
+GST_blacklist_handle_reply (void *cls,
+                            struct GNUNET_SERVER_Client *client,
                             const struct GNUNET_MessageHeader *message);
 
 
@@ -97,12 +99,13 @@
  *
  * @param cls closure
  * @param peer identity of peer that was tested
- * @param result GNUNET_OK if the connection is allowed,
- *               GNUNET_NO if not
+ * @param result #GNUNET_OK if the connection is allowed,
+ *               #GNUNET_NO if not
  */
-typedef void (*GST_BlacklistTestContinuation) (void *cls,
-                                               const struct GNUNET_PeerIdentity
-                                               * peer, int result);
+typedef void
+(*GST_BlacklistTestContinuation) (void *cls,
+                                  const struct GNUNET_PeerIdentity *peer,
+                                  int result);
 
 
 /**
@@ -111,9 +114,9 @@
  * @param peer the identity of the peer to test
  * @param transport_name name of the transport to test, never NULL
  * @param cont function to call with result
- * @param cont_cls closure for 'cont'
+ * @param cont_cls closure for @a cont
  * @return handle to the blacklist check, NULL if the decision
- *        was made instantly and 'cont' was already called
+ *        was made instantly and @a cont was already called
  */
 struct GST_BlacklistCheck *
 GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,

Modified: gnunet/src/transport/gnunet-service-transport_hello.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport_hello.h       2015-01-19 
01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/gnunet-service-transport_hello.h       2015-01-19 
01:08:03 UTC (rev 34943)
@@ -17,7 +17,6 @@
      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      Boston, MA 02111-1307, USA.
 */
-
 /**
  * @file transport/gnunet-service-transport_hello.h
  * @brief hello API
@@ -32,15 +31,15 @@
 #include "gnunet_hello_lib.h"
 
 
-
 /**
  * Signature of a function to call whenever our hello changes.
  *
  * @param cls closure
  * @param hello updated HELLO
  */
-typedef void (*GST_HelloCallback) (void *cls,
-                                   const struct GNUNET_MessageHeader * hello);
+typedef void
+(*GST_HelloCallback) (void *cls,
+                      const struct GNUNET_MessageHeader *hello);
 
 
 /**
@@ -48,10 +47,12 @@
  *
  * @param friend_only use a friend only hello
  * @param cb function to call whenever our HELLO changes
- * @param cb_cls closure for cb
+ * @param cb_cls closure for @a cb
  */
 void
-GST_hello_start (int friend_only, GST_HelloCallback cb, void *cb_cls);
+GST_hello_start (int friend_only,
+                 GST_HelloCallback cb,
+                 void *cb_cls);
 
 
 /**
@@ -73,7 +74,7 @@
 /**
  * Add or remove an address from this peer's HELLO message.
  *
- * @param addremove GNUNET_YES to add, GNUNET_NO to remove
+ * @param addremove #GNUNET_YES to add, #GNUNET_NO to remove
  * @param address address to add or remove
  */
 void
@@ -88,8 +89,8 @@
  * @param sig location where to cache PONG signatures for this address [set]
  * @param sig_expiration how long until the current 'sig' expires?
  *            (ZERO if sig was never created) [set]
- * @return GNUNET_YES if this is one of our addresses,
- *         GNUNET_NO if not
+ * @return #GNUNET_YES if this is one of our addresses,
+ *         #GNUNET_NO if not
  */
 int
 GST_hello_test_address (const struct GNUNET_HELLO_Address *address,

Modified: gnunet/src/transport/gnunet-service-transport_manipulation.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_manipulation.c        
2015-01-19 01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/gnunet-service-transport_manipulation.c        
2015-01-19 01:08:03 UTC (rev 34943)
@@ -39,6 +39,7 @@
   TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2
 };
 
+
 /**
  * Struct containing information about manipulations to a specific peer
  */
@@ -105,6 +106,7 @@
   struct DelayQueueEntry *send_tail;
 };
 
+
 struct GST_ManipulationHandle
 {
   /**
@@ -487,35 +489,39 @@
  * @param ats_count the number of ats information
  */
 struct GNUNET_ATS_Information *
-GST_manipulation_manipulate_metrics(const struct GNUNET_PeerIdentity *peer,
-    const struct GNUNET_HELLO_Address *address, struct Session *session,
-    const struct GNUNET_ATS_Information *ats, uint32_t ats_count)
+GST_manipulation_manipulate_metrics(const struct GNUNET_HELLO_Address *address,
+                                    struct Session *session,
+                                    const struct GNUNET_ATS_Information *ats,
+                                    uint32_t ats_count)
 {
-  struct GNUNET_ATS_Information *ats_new =
-      GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) *ats_count);
+  const struct GNUNET_PeerIdentity *peer = &address->peer;
+  struct GNUNET_ATS_Information *ats_new;
   struct TM_Peer *tmp;
   uint32_t m_tmp;
   uint32_t g_tmp;
-  int d;
-  tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer);
+  uint32_t d;
 
+  if (0 == ats_count)
+    return NULL;
+  ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * ats_count);
+  tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer);
   for (d = 0; d < ats_count; d++)
-    {
-      ats_new[d] = ats[d];
-      m_tmp = UINT32_MAX;
-      if (NULL != tmp)
-        m_tmp = find_metric(tmp, ntohl(ats[d].type), TM_RECEIVE);
-      g_tmp = find_metric(&man_handle.general, ntohl(ats[d].type), TM_RECEIVE);
+  {
+    ats_new[d] = ats[d];
+    m_tmp = UINT32_MAX;
+    if (NULL != tmp)
+      m_tmp = find_metric(tmp, ntohl(ats[d].type), TM_RECEIVE);
+    g_tmp = find_metric(&man_handle.general, ntohl(ats[d].type), TM_RECEIVE);
 
-      if (UINT32_MAX != g_tmp)
-        ats_new[d].value = htonl(g_tmp);
-      if (UINT32_MAX != m_tmp)
-        ats_new[d].value = htonl(m_tmp);
-    }
-
+    if (UINT32_MAX != g_tmp)
+      ats_new[d].value = htonl(g_tmp);
+    if (UINT32_MAX != m_tmp)
+      ats_new[d].value = htonl(m_tmp);
+  }
   return ats_new;
 }
 
+
 /**
  * Adapter function between transport plugins and transport receive function
  * manipulation delays for next send.
@@ -528,9 +534,9 @@
  */
 struct GNUNET_TIME_Relative
 GST_manipulation_recv (void *cls,
-    const struct GNUNET_HELLO_Address *address,
-    struct Session *session,
-    const struct GNUNET_MessageHeader *message)
+                       const struct GNUNET_HELLO_Address *address,
+                       struct Session *session,
+                       const struct GNUNET_MessageHeader *message)
 {
   struct TM_Peer *tmp;
   uint32_t p_recv_delay;

Modified: gnunet/src/transport/gnunet-service-transport_manipulation.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport_manipulation.h        
2015-01-19 01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/gnunet-service-transport_manipulation.h        
2015-01-19 01:08:03 UTC (rev 34943)
@@ -77,10 +77,11 @@
  */
 struct GNUNET_TIME_Relative
 GST_manipulation_recv (void *cls,
-    const struct GNUNET_HELLO_Address *address,
-    struct Session *session,
-    const struct GNUNET_MessageHeader *message);
+                       const struct GNUNET_HELLO_Address *address,
+                       struct Session *session,
+                       const struct GNUNET_MessageHeader *message);
 
+
 /**
  * Function that will be called to manipulate ATS information according to
  * current manipulation settings
@@ -90,14 +91,15 @@
  * @param session the session
  * @param ats the ats information
  * @param ats_count the number of ats information
+ * @return modified @a ats information
  */
 struct GNUNET_ATS_Information *
-GST_manipulation_manipulate_metrics (const struct GNUNET_PeerIdentity *peer,
-               const struct GNUNET_HELLO_Address *address,
-               struct Session *session,
-               const struct GNUNET_ATS_Information *ats,
-               uint32_t ats_count);
+GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address 
*address,
+                                     struct Session *session,
+                                     const struct GNUNET_ATS_Information *ats,
+                                     uint32_t ats_count);
 
+
 /**
  * Notify manipulation about disconnect so it can discard queued messages
  *

Modified: gnunet/src/transport/gnunet-service-transport_neighbours.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_neighbours.c  2015-01-19 
01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/gnunet-service-transport_neighbours.c  2015-01-19 
01:08:03 UTC (rev 34943)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2010-2013 Christian Grothoff (and other contributing authors)
+     (C) 2010-2015 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -25,13 +25,14 @@
  */
 #include "platform.h"
 #include "gnunet_ats_service.h"
+#include "gnunet-service-transport_ats.h"
+#include "gnunet-service-transport_blacklist.h"
+#include "gnunet-service-transport_clients.h"
 #include "gnunet-service-transport_neighbours.h"
 #include "gnunet-service-transport_plugins.h"
 #include "gnunet-service-transport_validation.h"
-#include "gnunet-service-transport_clients.h"
 #include "gnunet-service-transport.h"
 #include "gnunet_peerinfo_service.h"
-#include "gnunet-service-transport_blacklist.h"
 #include "gnunet_constants.h"
 #include "transport.h"
 
@@ -255,8 +256,6 @@
 };
 
 
-
-
 /**
  * A possible address we could use to communicate with a neighbour.
  */
@@ -301,6 +300,7 @@
   uint32_t keep_alive_nonce;
 };
 
+
 /**
  * Entry in neighbours.
  */
@@ -344,12 +344,12 @@
    * Main task that drives this peer (timeouts, keepalives, etc.).
    * Always runs the 'master_task'.
    */
-  struct GNUNET_SCHEDULER_Task * task;
+  struct GNUNET_SCHEDULER_Task *task;
 
   /**
    * Task to disconnect neighbour after we received a DISCONNECT message
    */
-  struct GNUNET_SCHEDULER_Task * delayed_disconnect_task;
+  struct GNUNET_SCHEDULER_Task *delayed_disconnect_task;
 
   /**
    * At what time should we sent the next keep-alive message?
@@ -480,7 +480,7 @@
 
 
 /**
- * Hash map from peer identities to the respective 'struct NeighbourMapEntry'.
+ * Hash map from peer identities to the respective `struct NeighbourMapEntry`.
  */
 static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
 
@@ -541,9 +541,15 @@
  */
 static struct GNUNET_SCHEDULER_Task * util_transmission_tk;
 
-
+/**
+ * FIXME
+ */
 static struct GNUNET_CONTAINER_MultiPeerMap *registered_quota_notifications;
 
+
+/**
+ * FIXME
+ */
 static char *
 print_ack_state (enum GST_ACK_State s)
 {
@@ -589,6 +595,7 @@
   return GNUNET_TRANSPORT_is_connected (n->state);
 }
 
+
 /**
  * Send information about a new outbound quota to our clients.
  *
@@ -701,9 +708,10 @@
     struct GNUNET_TIME_Absolute timeout)
 {
   n->timeout = timeout;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' changed timeout %s\n",
-      GNUNET_i2s (&n->id),
-      GNUNET_STRINGS_absolute_time_to_string (timeout));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Neighbour `%s' changed timeout %s\n",
+              GNUNET_i2s (&n->id),
+              GNUNET_STRINGS_absolute_time_to_string (timeout));
   neighbour_change_cb (callback_cls,
       &n->id,
       n->primary_address.address,
@@ -732,6 +740,7 @@
              struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
 {
   struct GNUNET_TRANSPORT_PluginFunctions *papi;
+
   if (NULL == (papi = GST_plugins_find (address->transport_name)))
   {
     GNUNET_break (0);
@@ -750,15 +759,20 @@
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Failed to obtain new session for peer `%s' and  address 
'%s'\n",
-                GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
-    GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
+                GNUNET_i2s (&address->peer),
+                GST_plugins_a2s (address));
+    GNUNET_STATISTICS_update (GST_stats,
+                              gettext_noop ("# session creation failed"),
+                              1,
+                              GNUNET_NO);
     return;
   }
+  GST_ats_new_session (address, session);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Neighbour `%s' configured alternative address %s\n",
+              GNUNET_i2s (&n->id),
+              GST_plugins_a2s(address));
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' configured alternative 
address %s\n",
-      GNUNET_i2s (&n->id),
-      GST_plugins_a2s(address));
-
   n->alternative_address.address = GNUNET_HELLO_address_copy (address);
   n->alternative_address.bandwidth_in = bandwidth_in;
   n->alternative_address.bandwidth_out = bandwidth_out;
@@ -802,8 +816,13 @@
     if (is_active != n->primary_address.ats_active)
     {
       n->primary_address.ats_active = is_active;
-      GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, 
n->primary_address.session, is_active);
-      GST_validation_set_address_use (n->primary_address.address, 
n->primary_address.session, is_active);
+      GNUNET_ATS_address_in_use (GST_ats,
+                                 n->primary_address.address,
+                                 n->primary_address.session,
+                                 is_active);
+      GST_validation_set_address_use (n->primary_address.address,
+                                      n->primary_address.session,
+                                      is_active);
     }
     if (GNUNET_YES == is_active)
     {
@@ -820,10 +839,13 @@
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Failed to obtain new session for peer `%s' and  address 
'%s'\n",
                GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
-    GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
+    GNUNET_STATISTICS_update (GST_stats,
+                              gettext_noop ("# session creation failed"),
+                              1,
+                              GNUNET_NO);
     return;
   }
-
+  GST_ats_new_session (address, session);
   n->primary_address.address = GNUNET_HELLO_address_copy (address);
   n->primary_address.bandwidth_in = bandwidth_in;
   n->primary_address.bandwidth_out = bandwidth_out;
@@ -833,24 +855,31 @@
   if (GNUNET_YES == is_active)
   {
     /* Telling ATS about new session */
-    GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, 
n->primary_address.session, GNUNET_YES);
-    GST_validation_set_address_use (n->primary_address.address, 
n->primary_address.session, GNUNET_YES);
+    GNUNET_ATS_address_in_use (GST_ats,
+                               n->primary_address.address,
+                               n->primary_address.session,
+                               GNUNET_YES);
+    GST_validation_set_address_use (n->primary_address.address,
+                                    n->primary_address.session,
+                                    GNUNET_YES);
     GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
     send_outbound_quota (&address->peer, bandwidth_out);
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' switched to address 
`%s'\n",
-      GNUNET_i2s (&n->id),
-      GST_plugins_a2s(address));
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Neighbour `%s' switched to address `%s'\n",
+              GNUNET_i2s (&n->id),
+              GST_plugins_a2s(address));
 
   neighbour_change_cb (callback_cls,
-      &n->id,
-      n->primary_address.address,
-      n->state, n->timeout,
-      n->primary_address.bandwidth_in,
-      n->primary_address.bandwidth_out);
+                       &n->id,
+                       n->primary_address.address,
+                       n->state, n->timeout,
+                       n->primary_address.bandwidth_in,
+                       n->primary_address.bandwidth_out);
 }
 
+
 /**
  * Clear the primary address of a neighbour since this address is not
  * valid anymore and notify monitoring about it
@@ -865,13 +894,14 @@
 
   /* Notify monitoring about it */
   neighbour_change_cb (callback_cls,
-      &n->id,
-      NULL,
-      n->state, n->timeout,
-      n->primary_address.bandwidth_in,
-      n->primary_address.bandwidth_out);
+                       &n->id,
+                       NULL,
+                       n->state, n->timeout,
+                       n->primary_address.bandwidth_in,
+                       n->primary_address.bandwidth_out);
 }
 
+
 /**
  * Clear the alternative address of a neighbour since this address is not
  * valid anymore
@@ -885,6 +915,7 @@
   free_address (&n->alternative_address);
 }
 
+
 /**
  * Free a neighbour map entry.
  *
@@ -937,6 +968,8 @@
   free_address (&n->alternative_address);
 
   /* cut all transport-level connection for this peer */
+  // FIXME: might want to revisit this; maybe just
+  // shorten session timeout on plugin level?
   if ((GNUNET_NO == keep_sessions) &&
       (NULL != backup_primary) &&
       (NULL != (papi = GST_plugins_find (backup_primary->transport_name))))
@@ -1369,7 +1402,7 @@
  */
 void
 GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour,
-    const struct GNUNET_MessageHeader *m)
+                          const struct GNUNET_MessageHeader *m)
 {
   struct NeighbourMapEntry *n;
   const struct SessionKeepAliveMessage *msg_in;
@@ -1422,7 +1455,7 @@
  */
 void
 GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
-    const struct GNUNET_MessageHeader *m)
+                                   const struct GNUNET_MessageHeader *m)
 {
   struct NeighbourMapEntry *n;
   const struct SessionKeepAliveMessage *msg;
@@ -1505,8 +1538,9 @@
   else
     latency = n->latency.rel_value_us;
   ats.value = htonl (latency);
-  GST_ats_update_metrics (&n->id, n->primary_address.address,
-      n->primary_address.session, &ats, 1);
+  GST_ats_update_metrics (n->primary_address.address,
+                          n->primary_address.session,
+                          &ats, 1);
 }
 
 
@@ -1655,12 +1689,13 @@
   n->task = GNUNET_SCHEDULER_add_now (&master_task, n);
 }
 
+
 static void
 send_session_connect_cont (void *cls,
-                      const struct GNUNET_PeerIdentity *target,
-                      int result,
-                      size_t size_payload,
-                      size_t size_on_wire)
+                           const struct GNUNET_PeerIdentity *target,
+                           int result,
+                           size_t size_payload,
+                           size_t size_on_wire)
 {
   struct NeighbourMapEntry *n;
 
@@ -1686,26 +1721,20 @@
     return;
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-            _("Failed to send SYN message to peer `%s' using address `%s' 
session %p\n"),
-            GNUNET_i2s (target),
-            GST_plugins_a2s (n->primary_address.address),
-            n->primary_address.session);
+              _("Failed to send SYN message to peer `%s' using address `%s' 
session %p\n"),
+              GNUNET_i2s (target),
+              GST_plugins_a2s (n->primary_address.address),
+              n->primary_address.session);
 
   switch (n->state) {
   case GNUNET_TRANSPORT_PS_SYN_SENT:
     /* Remove address and request and additional one */
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
-        n->primary_address.session);
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL );
     unset_primary_address (n);
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
-        GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
+                           GNUNET_TIME_relative_to_absolute 
(FAST_RECONNECT_TIMEOUT));
     break;
   case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
     /* Remove address and request and additional one */
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
-        n->primary_address.session);
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL );
     unset_primary_address (n);
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
         GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -1714,10 +1743,6 @@
     /* Remove address and request and go back to primary address */
     GNUNET_STATISTICS_update (GST_stats, gettext_noop
         ("# Failed attempts to switch addresses (failed to send SYN CONT)"), 
1, GNUNET_NO);
-    GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address,
-        n->alternative_address.session);
-    GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address,
-        NULL );
     unset_alternative_address (n);
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
         GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -1756,6 +1781,8 @@
     GNUNET_break (0);
     return;
   }
+  GST_ats_new_session (na->address,
+                       na->session);
   GNUNET_STATISTICS_update (GST_stats,
                             gettext_noop
                             ("# SYN messages sent"),
@@ -1811,8 +1838,6 @@
         disconnect_neighbour (n);
         break;
     }
-    GNUNET_ATS_address_destroyed (GST_ats, na->address, na->session);
-    GNUNET_ATS_address_destroyed (GST_ats, na->address, NULL);
   }
   GST_neighbours_notify_data_sent (&na->address->peer,
                                    na->address,
@@ -1855,12 +1880,6 @@
             GST_plugins_a2s (n->primary_address.address),
             n->primary_address.session);
 
-  /* Failed to send SYN_ACK message with this address */
-  GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
-      n->primary_address.session);
-  GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
-      NULL);
-
   /* Remove address and request and additional one */
   unset_primary_address (n);
   n->ack_state = ACK_SEND_SYN_ACK;
@@ -1903,6 +1922,7 @@
     GNUNET_break (0);
     return;
   }
+  GST_ats_new_session (address, session);
   GNUNET_STATISTICS_update (GST_stats,
                             gettext_noop
                             ("# SYN_ACK messages sent"),
@@ -1929,17 +1949,6 @@
       GNUNET_break (0);
       return;
     }
-    /* Hard failure to send the SYN_ACK message with this address:
-       Destroy session (and address)  */
-    if (GNUNET_YES == GNUNET_HELLO_address_check_option(address,
-        GNUNET_HELLO_ADDRESS_INFO_INBOUND))
-    {
-      GNUNET_ATS_address_destroyed (GST_ats, address, session);
-      GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
-    }
-    else
-      GNUNET_ATS_address_destroyed (GST_ats, address, session);
-
     /* Remove address and request and additional one */
     unset_primary_address (n);
     n->ack_state = ACK_SEND_SYN_ACK;
@@ -1973,7 +1982,9 @@
   struct QuotaNotificationRequest *qnr = value;
 
   if ((qnr->session == qnr_ctx->session) &&
-      (0 == memcmp (&qnr->peer, &qnr_ctx->peer, sizeof (struct 
GNUNET_PeerIdentity))) &&
+      (0 == memcmp (&qnr->peer,
+                    &qnr_ctx->peer,
+                    sizeof (struct GNUNET_PeerIdentity))) &&
       (0 == strcmp(qnr_ctx->plugin, qnr->plugin)))
   {
     qnr_ctx->res = value;
@@ -1982,10 +1993,12 @@
   return GNUNET_YES;
 }
 
+
 void
-GST_neighbours_register_quota_notification(void *cls,
-    const struct GNUNET_PeerIdentity *peer, const char *plugin,
-    struct Session *session)
+GST_neighbours_register_quota_notification (void *cls,
+                                            const struct GNUNET_PeerIdentity 
*peer,
+                                            const char *plugin,
+                                            struct Session *session)
 {
   struct QuotaNotificationRequest *qnr;
   struct QNR_LookContext qnr_ctx;
@@ -2024,7 +2037,9 @@
 
 void
 GST_neighbours_unregister_quota_notification(void *cls,
-    const struct GNUNET_PeerIdentity *peer, const char *plugin, struct Session 
*session)
+                                             const struct GNUNET_PeerIdentity 
*peer,
+                                             const char *plugin,
+                                             struct Session *session)
 {
   struct QNR_LookContext qnr_ctx;
 
@@ -2056,8 +2071,11 @@
   GNUNET_free (qnr_ctx.res);
 }
 
+
 static int
-notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
+notification_cb (void *cls,
+                 const struct GNUNET_PeerIdentity *key,
+                 void *value)
 {
   /* struct NeighbourMapEntry *n = cls; */
   struct QuotaNotificationRequest *qnr = value;
@@ -2082,9 +2100,11 @@
   return GNUNET_OK;
 }
 
+
 static int
-free_notification_cb(void *cls, const struct GNUNET_PeerIdentity *key,
-    void *value)
+free_notification_cb (void *cls,
+                      const struct GNUNET_PeerIdentity *key,
+                      void *value)
 {
   /* struct NeighbourMapEntry *n = cls; */
   struct QuotaNotificationRequest *qnr = value;
@@ -2097,8 +2117,9 @@
   return GNUNET_OK;
 }
 
+
 static void
-inbound_bw_tracker_update(void *cls)
+inbound_bw_tracker_update (void *cls)
 {
   struct NeighbourMapEntry *n = cls;
 
@@ -2144,18 +2165,44 @@
 }
 
 
+/**
+ * FIXME
+ */
 struct BlacklistCheckSwitchContext
 {
+  /**
+   * FIXME
+   */
   struct BlacklistCheckSwitchContext *prev;
+
+  /**
+   * FIXME
+   */
   struct BlacklistCheckSwitchContext *next;
 
-
+  /**
+   * FIXME
+   */
   struct GST_BlacklistCheck *blc;
 
+  /**
+   * FIXME
+   */
   struct GNUNET_HELLO_Address *address;
+
+  /**
+   * FIXME
+   */
   struct Session *session;
 
+  /**
+   * FIXME
+   */
   struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
+
+  /**
+   * FIXME
+   */
   struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
 };
 
@@ -2465,18 +2512,13 @@
           GNUNET_i2s (&blc_ctx->address->peer));
     }
 
-    /* This address is blacklisted, delete address and session (if existing) 
in ATS */
-    GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, blc_ctx->session);
+    /* This address is blacklisted, delete session */
+    /* FIXME: tell plugin to force killing session here and now! */
 
-    if ( (GNUNET_YES == (GNUNET_HELLO_address_check_option (blc_ctx->address,
-          GNUNET_HELLO_ADDRESS_INFO_INBOUND))) && (NULL != blc_ctx->session))
-    {
-      /* This is an inbound address, destroy full  address */
-      GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, NULL );
-    }
-
     /* Remove blacklist check and clean up */
-    GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, blc_ctx);
+    GNUNET_CONTAINER_DLL_remove (pending_bc_head,
+                                 pending_bc_tail,
+                                 blc_ctx);
     GNUNET_HELLO_address_free (blc_ctx->address);
     GNUNET_free (blc_ctx);
     return;
@@ -2484,10 +2526,17 @@
 
   if (NULL == blc_ctx->session)
   {
-    blc_ctx->session = papi->get_session (papi->cls, blc_ctx->address);
+    blc_ctx->session = papi->get_session (papi->cls,
+                                          blc_ctx->address);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Obtained new session for peer `%s' and  address '%s': %p\n",
-                GNUNET_i2s (&blc_ctx->address->peer), GST_plugins_a2s 
(blc_ctx->address), blc_ctx->session);
+                GNUNET_i2s (&blc_ctx->address->peer),
+                GST_plugins_a2s (blc_ctx->address),
+                blc_ctx->session);
+    if (NULL != blc_ctx->session)
+      GST_ats_new_session (blc_ctx->address,
+                           blc_ctx->session);
+
   }
   if (NULL == blc_ctx->session)
   {
@@ -2497,9 +2546,9 @@
                 GNUNET_i2s (&blc_ctx->address->peer),
                 GST_plugins_a2s (blc_ctx->address));
     /* Delete address in ATS */
-    GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, NULL);
-
-    GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, blc_ctx);
+    GNUNET_CONTAINER_DLL_remove (pending_bc_head,
+                                 pending_bc_tail,
+                                 blc_ctx);
     GNUNET_HELLO_address_free (blc_ctx->address);
     GNUNET_free (blc_ctx);
     return;
@@ -2721,21 +2770,15 @@
   if (NULL == (GST_plugins_find (address->transport_name)))
   {
     /* we don't have the plugin for this address */
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Plugin `%s' is unknown, suggestion for peer %s ignored\n",
-                address->transport_name,
-                GNUNET_i2s (peer));
-    GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
+    GNUNET_break (0);
     return;
   }
   if ((NULL == session) &&
-      (GNUNET_HELLO_address_check_option (address, 
GNUNET_HELLO_ADDRESS_INFO_INBOUND)))
+      (GNUNET_HELLO_address_check_option (address,
+                                          GNUNET_HELLO_ADDRESS_INFO_INBOUND)))
   {
     /* This is a inbound address and we do not have a session to use! */
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Inbound address without session `%s'! Destroying 
address...\n",
-                GST_plugins_a2s (address));
-    GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
+    GNUNET_break (0);
     return;
   }
 
@@ -2766,6 +2809,15 @@
 }
 
 
+/**
+ * Function called to send network utilization data to ATS for
+ * each active connection.
+ *
+ * @param cls NULL
+ * @param key peer we send utilization data for
+ * @param value the `struct NeighbourMapEntry *` with data to send
+ * @return #GNUNET_OK (continue to iterate)
+ */
 static int
 send_utilization_data (void *cls,
                        const struct GNUNET_PeerIdentity *key,
@@ -2779,6 +2831,8 @@
   uint32_t bps_out;
   struct GNUNET_TIME_Relative delta;
 
+  if (GNUNET_TRANSPORT_PS_CONNECTED != n->state)
+    return GNUNET_OK;
   delta = GNUNET_TIME_absolute_get_difference (n->last_util_transmission,
                                                GNUNET_TIME_absolute_get ());
 
@@ -2817,8 +2871,9 @@
   atsi[3].type = htonl (GNUNET_ATS_UTILIZATION_PAYLOAD_IN);
   atsi[3].value = htonl (bps_pl_in);
 
-  GST_ats_update_metrics (key, n->primary_address.address,
-      n->primary_address.session, atsi, 4);
+  GST_ats_update_metrics (n->primary_address.address,
+                          n->primary_address.session,
+                          atsi, 4);
   n->util_payload_bytes_recv = 0;
   n->util_payload_bytes_sent = 0;
   n->util_total_bytes_recv = 0;
@@ -2952,12 +3007,6 @@
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  "Connection to `%s' timed out waiting for other peer to send 
SYN_ACK\n",
                  GNUNET_i2s (&n->id));
-      /* We could not send to this address, delete address and session */
-      if (NULL != n->primary_address.session)
-        GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
-            n->primary_address.session);
-      GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
-
       /* Remove address and request and additional one */
       unset_primary_address (n);
       set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
@@ -3023,8 +3072,10 @@
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs 
(after trying to SYN on alternative address)\n",
                  GNUNET_i2s (&n->id));
-      GNUNET_STATISTICS_update (GST_stats, gettext_noop
-          ("# Failed attempts to switch addresses (no response)"), 1, 
GNUNET_NO);
+      GNUNET_STATISTICS_update (GST_stats,
+                                gettext_noop ("# Failed attempts to switch 
addresses (no response)"),
+                                1,
+                                GNUNET_NO);
       disconnect_neighbour (n);
       return;
     }
@@ -3161,17 +3212,12 @@
                        n->primary_address.bandwidth_in,
                        n->primary_address.bandwidth_out);
     /* Tell ATS that the outbound session we created to send SYN was 
successful */
-    // FIXME: shouldn't ATS already know about *outbound* sessions
-    // in particular?
-    GST_ats_add_address (n->primary_address.address,
+    set_primary_address (n,
+                         n->primary_address.address,
                          n->primary_address.session,
-                         NULL, 0);
-    set_primary_address (n,
-                n->primary_address.address,
-                n->primary_address.session,
-                n->primary_address.bandwidth_in,
-                n->primary_address.bandwidth_out,
-                GNUNET_YES);
+                         n->primary_address.bandwidth_in,
+                         n->primary_address.bandwidth_out,
+                         GNUNET_YES);
     send_session_ack_message (n);
     break;
   case GNUNET_TRANSPORT_PS_SYN_RECV_ATS:
@@ -3202,13 +3248,9 @@
   case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
     /* new address worked; adopt it and go back to connected! */
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
-        GNUNET_TIME_relative_to_absolute 
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
+                           GNUNET_TIME_relative_to_absolute 
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
     GNUNET_break (GNUNET_NO == n->alternative_address.ats_active);
 
-    /* Notify about session... perhaps we obtained it */
-    // FIXME: why is this needed?
-    GST_ats_add_address (n->alternative_address.address,
-        n->alternative_address.session, NULL, 0);
     /* Set primary addresses */
     set_primary_address (n, n->alternative_address.address,
         n->alternative_address.session, n->alternative_address.bandwidth_in,
@@ -3309,7 +3351,6 @@
                 GNUNET_i2s (peer));
 
     /* Destroy the address since it cannot be used */
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
     unset_primary_address (n);
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
         GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -3337,9 +3378,7 @@
                 GST_plugins_a2s (n->primary_address.address),
                 n->primary_address.session,
                 GNUNET_i2s (peer));
-
     /* Destroy the address since it cannot be used */
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
     unset_primary_address (n);
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
         GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -3358,13 +3397,7 @@
         n->alternative_address.session);
 
     /* Destroy the inbound address since it cannot be used */
-    if (GNUNET_YES
-        == GNUNET_HELLO_address_check_option (n->primary_address.address,
-            GNUNET_HELLO_ADDRESS_INFO_INBOUND))
-      GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
     free_address (&n->primary_address);
-
-
     n->primary_address = n->alternative_address;
     memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress));
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_SENT,
@@ -3487,20 +3520,13 @@
   set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
     GNUNET_TIME_relative_to_absolute 
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
 
-  /* Add session to ATS since no session was given (NULL) and we may have
-   * obtained a new session */
-  // FIXME: likely not the best place to do this...
-  GST_ats_add_address (n->primary_address.address,
-                       n->primary_address.session,
-                       NULL, 0);
-
   /* Set primary address to used */
   set_primary_address (n,
-              n->primary_address.address,
-              n->primary_address.session,
-              n->primary_address.bandwidth_in,
-              n->primary_address.bandwidth_out,
-              GNUNET_YES);
+                       n->primary_address.address,
+                       n->primary_address.session,
+                       n->primary_address.bandwidth_in,
+                       n->primary_address.bandwidth_out,
+                       GNUNET_YES);
   return GNUNET_OK;
 }
 
@@ -3554,8 +3580,10 @@
   disconnect_neighbour (n);
 }
 
-void delayed_disconnect (void *cls,
-    const struct GNUNET_SCHEDULER_TaskContext* tc)
+
+static void
+delayed_disconnect (void *cls,
+                    const struct GNUNET_SCHEDULER_TaskContext* tc)
 {
   struct NeighbourMapEntry *n = cls;
 
@@ -3563,11 +3591,6 @@
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Disconnecting by request from peer %s\n",
               GNUNET_i2s (&n->id));
-
-  if (NULL != n->primary_address.address)
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
-        n->primary_address.session);
-
   free_neighbour (n, GNUNET_NO);
 }
 
@@ -3871,16 +3894,18 @@
     GNUNET_SCHEDULER_cancel (util_transmission_tk);
     util_transmission_tk = NULL;
   }
-
-  GNUNET_CONTAINER_multipeermap_iterate (neighbours, 
&disconnect_all_neighbours,
-      NULL );
+  GNUNET_CONTAINER_multipeermap_iterate (neighbours,
+                                         &disconnect_all_neighbours,
+                                         NULL);
   GNUNET_CONTAINER_multipeermap_destroy (neighbours);
 
   next = pending_bc_head;
-  for (cur = next; NULL != cur; cur = next )
+  for (cur = next; NULL != cur; cur = next)
   {
     next = cur->next;
-    GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, cur);
+    GNUNET_CONTAINER_DLL_remove (pending_bc_head,
+                                 pending_bc_tail,
+                                 cur);
 
     if (NULL != cur->blc)
     {
@@ -3893,7 +3918,7 @@
   }
 
   GNUNET_CONTAINER_multipeermap_iterate (registered_quota_notifications,
-      &free_notification_cb, NULL);
+                                         &free_notification_cb, NULL);
   GNUNET_CONTAINER_multipeermap_destroy (registered_quota_notifications);
   registered_quota_notifications = NULL;
 

Modified: gnunet/src/transport/gnunet-service-transport_neighbours.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport_neighbours.h  2015-01-19 
01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/gnunet-service-transport_neighbours.h  2015-01-19 
01:08:03 UTC (rev 34943)
@@ -86,10 +86,14 @@
  *
  * @param cls closure
  * @param success #GNUNET_OK on success, #GNUNET_NO on failure, #GNUNET_SYSERR 
if we're not connected
+ * @param bytes_payload how much payload was transmitted
+ * @param bytes_on_wire how many bytes were used on the wire
  */
-typedef void (*GST_NeighbourSendContinuation) (void *cls, int success,
-                                               size_t bytes_payload,
-                                               size_t bytes_on_wire);
+typedef void
+(*GST_NeighbourSendContinuation) (void *cls,
+                                  int success,
+                                  size_t bytes_payload,
+                                  size_t bytes_on_wire);
 
 
 /**
@@ -103,20 +107,34 @@
  * @param cont_cls closure for @a cont
  */
 void
-GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg,
-                     size_t msg_size, struct GNUNET_TIME_Relative timeout,
+GST_neighbours_send (const struct GNUNET_PeerIdentity *target,
+                     const void *msg,
+                     size_t msg_size,
+                     struct GNUNET_TIME_Relative timeout,
                      GST_NeighbourSendContinuation cont, void *cont_cls);
 
+
+
+/**
+ * FIXME
+ */
 void
 GST_neighbours_register_quota_notification (void *cls,
                                            const struct GNUNET_PeerIdentity 
*peer,
                                            const char *plugin,
                                            struct Session *session);
 
+
+/**
+ * FIXME
+ */
 void
-GST_neighbours_unregister_quota_notification(void *cls,
-    const struct GNUNET_PeerIdentity *peer, const char *plugin, struct Session 
*session);
+GST_neighbours_unregister_quota_notification (void *cls,
+                                              const struct GNUNET_PeerIdentity 
*peer,
+                                              const char *plugin,
+                                              struct Session *session);
 
+
 /**
  * We have received a message from the given sender.
  * How long should we delay before receiving more?
@@ -129,8 +147,9 @@
  * @return how long to wait before reading more from this sender
  */
 struct GNUNET_TIME_Relative
-GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity
-                                        *sender, ssize_t size, int 
*do_forward);
+GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity 
*sender,
+                                        ssize_t size,
+                                        int *do_forward);
 
 
 /**
@@ -155,7 +174,7 @@
  */
 void
 GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
-    const struct GNUNET_MessageHeader *m);
+                                   const struct GNUNET_MessageHeader *m);
 
 
 /**
@@ -189,13 +208,14 @@
  * @param bandwidth_in inbound quota in NBO
  * @param bandwidth_out outbound quota in NBO
  */
-typedef void (*GST_NeighbourIterator) (void *cls,
-                                       const struct GNUNET_PeerIdentity 
*neighbour,
-                                       const struct GNUNET_HELLO_Address 
*address,
-                                       enum GNUNET_TRANSPORT_PeerState state,
-                                       struct GNUNET_TIME_Absolute 
state_timeout,
-                                       struct GNUNET_BANDWIDTH_Value32NBO 
bandwidth_in,
-                                       struct GNUNET_BANDWIDTH_Value32NBO 
bandwidth_out);
+typedef void
+(*GST_NeighbourIterator) (void *cls,
+                          const struct GNUNET_PeerIdentity *neighbour,
+                          const struct GNUNET_HELLO_Address *address,
+                          enum GNUNET_TRANSPORT_PeerState state,
+                          struct GNUNET_TIME_Absolute state_timeout,
+                          struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+                          struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out);
 
 
 /**
@@ -221,6 +241,9 @@
                                    struct Session *session);
 
 
+/**
+ * FIXME
+ */
 void
 GST_neighbours_notify_data_recv (const struct GNUNET_PeerIdentity *peer,
                                  const struct GNUNET_HELLO_Address *address,
@@ -228,6 +251,9 @@
                                  const struct GNUNET_MessageHeader *message);
 
 
+/**
+ * FIXME
+ */
 void
 GST_neighbours_notify_payload_recv (const struct GNUNET_PeerIdentity *peer,
                                     const struct GNUNET_HELLO_Address *address,
@@ -235,11 +261,17 @@
                                     const struct GNUNET_MessageHeader 
*message);
 
 
+/**
+ * FIXME
+ */
 void
 GST_neighbours_notify_payload_sent (const struct GNUNET_PeerIdentity *peer,
                                     size_t size);
 
 
+/**
+ * FIXME
+ */
 void
 GST_neighbours_notify_data_sent (const struct GNUNET_PeerIdentity *peer,
                                  const struct GNUNET_HELLO_Address *address,
@@ -276,14 +308,14 @@
  */
 int
 GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
-                               const struct GNUNET_PeerIdentity *peer);
+                                   const struct GNUNET_PeerIdentity *peer);
 
 
 /**
  * We received a 'SESSION_CONNECT_ACK' message from the other peer.
  * Consider switching to it.
  *
- * @param message possibly a 'struct SessionConnectMessage' (check format)
+ * @param message possibly a `struct SessionConnectMessage` (check format)
  * @param peer identity of the peer to switch the address for
  * @param address address of the other peer, NULL if other peer
  *                       connected to us
@@ -292,9 +324,9 @@
  */
 int
 GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader 
*message,
-                                   const struct GNUNET_PeerIdentity *peer,
-                                   const struct GNUNET_HELLO_Address *address,
-                                   struct Session *session);
+                                       const struct GNUNET_PeerIdentity *peer,
+                                       const struct GNUNET_HELLO_Address 
*address,
+                                       struct Session *session);
 
 
 /**
@@ -345,10 +377,8 @@
  * @param msg the disconnect message
  */
 void
-GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity
-                                          *peer,
-                                          const struct GNUNET_MessageHeader
-                                          *msg);
+GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity 
*peer,
+                                          const struct GNUNET_MessageHeader 
*msg);
 
 
 #endif

Modified: gnunet/src/transport/gnunet-service-transport_validation.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_validation.c  2015-01-19 
01:05:57 UTC (rev 34942)
+++ gnunet/src/transport/gnunet-service-transport_validation.c  2015-01-19 
01:08:03 UTC (rev 34943)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2010-2014 Christian Grothoff (and other contributing authors)
+     (C) 2010-2015 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -24,12 +24,13 @@
  * @author Christian Grothoff
  */
 #include "platform.h"
+#include "gnunet-service-transport_ats.h"
+#include "gnunet-service-transport_blacklist.h"
 #include "gnunet-service-transport_clients.h"
-#include "gnunet-service-transport_validation.h"
-#include "gnunet-service-transport_plugins.h"
 #include "gnunet-service-transport_hello.h"
-#include "gnunet-service-transport_blacklist.h"
 #include "gnunet-service-transport_neighbours.h"
+#include "gnunet-service-transport_plugins.h"
+#include "gnunet-service-transport_validation.h"
 #include "gnunet-service-transport.h"
 #include "gnunet_hello_lib.h"
 #include "gnunet_ats_service.h"
@@ -253,6 +254,7 @@
    * Current state of this validation entry
    */
   enum GNUNET_TRANSPORT_ValidationState state;
+
   /**
    * Challenge number we used.
    */
@@ -275,6 +277,11 @@
   int expecting_pong;
 
   /**
+   * Is this address known to ATS as valid right now?
+   */
+  int known_to_ats;
+
+  /**
    * Which network type does our address belong to?
    */
   enum GNUNET_ATS_Network_Type network;
@@ -445,6 +452,11 @@
   GNUNET_break (GNUNET_OK ==
                 GNUNET_CONTAINER_multipeermap_remove (validation_map,
                                                       &ve->pid, ve));
+  if (GNUNET_YES == ve->known_to_ats)
+  {
+    GST_ats_expire_address (ve->address);
+    ve->known_to_ats = GNUNET_NO;
+  }
   GNUNET_HELLO_address_free (ve->address);
   if (NULL != ve->timeout_task)
   {
@@ -593,7 +605,8 @@
     {
       GNUNET_assert (NULL != papi->send);
       GNUNET_assert (NULL != papi->get_session);
-      struct Session * session = papi->get_session(papi->cls, ve->address);
+      struct Session *session = papi->get_session (papi->cls,
+                                                   ve->address);
 
       if (NULL != session)
       {
@@ -847,8 +860,11 @@
 
   ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
   ats.value = htonl (ve->network);
-  GNUNET_ATS_address_add (GST_ats, address, NULL, &ats, 1);
-
+  if (GNUNET_YES != ve->known_to_ats)
+  {
+    ve->known_to_ats = GNUNET_YES;
+    GST_ats_add_address (address, NULL, &ats, 1);
+  }
   return GNUNET_OK;
 }
 
@@ -975,6 +991,7 @@
      GNUNET_break (0);
      return;
   }
+  GST_ats_new_session (address, session);
   papi->send (papi->cls, session,
               (const char *) pong,
               ntohs (pong->header.size),
@@ -1190,18 +1207,19 @@
 
   /* first see if the session we got this PING from can be used to transmit
    * a response reliably */
-  if (papi == NULL)
+  if (NULL == papi)
+  {
     ret = -1;
+  }
   else
   {
-    GNUNET_assert (papi->send != NULL);
-    GNUNET_assert (papi->get_session != NULL);
-
-    if (session == NULL)
+    GNUNET_assert (NULL != papi->send);
+    GNUNET_assert (NULL != papi->get_session);
+    if (NULL == session)
     {
       session = papi->get_session (papi->cls, sender_address);
     }
-    if (session == NULL)
+    if (NULL == session)
     {
       GNUNET_break (0);
       ret = -1;
@@ -1491,8 +1509,15 @@
     ats[0].value = htonl ((uint32_t) ve->latency.rel_value_us);
     ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
     ats[1].value = htonl ((uint32_t) ve->network);
-    // FIXME: add vs. update!
-    GNUNET_ATS_address_add (GST_ats, ve->address, NULL, ats, 2);
+    if (GNUNET_YES == ve->known_to_ats)
+    {
+      GST_ats_update_metrics (ve->address, NULL, ats, 2);
+    }
+    else
+    {
+      ve->known_to_ats = GNUNET_YES;
+      GST_ats_add_address (ve->address, NULL, ats, 2);
+    }
   }
   if (validations_running > 0)
   {
@@ -1668,7 +1693,6 @@
   }
   if (ve->in_use == in_use)
   {
-
     if (GNUNET_YES == in_use)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,




reply via email to

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