REST/NAMESTORE: rework API
[oweals/gnunet.git] / src / transport / plugin_transport_unix.c
index 7dff9587fa64ea07dca7b5e09f199b7251a40ff3..5d095236d6ea5196a656b0484d8902c4ac713390 100644 (file)
@@ -1,21 +1,21 @@
 /*
      This file is part of GNUnet
-     (C) 2010-2014 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2010-2014 GNUnet e.V.
 
-     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 free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     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.
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-     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.
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 
 /**
@@ -137,7 +137,7 @@ struct UNIXMessageWrapper
   /**
    * Session this message belongs to.
    */
-  struct Session *session;
+  struct GNUNET_ATS_Session *session;
 
   /**
    * Function to call upon transmission.
@@ -174,18 +174,18 @@ struct UNIXMessageWrapper
 /**
  * Handle for a session.
  */
-struct Session
+struct GNUNET_ATS_Session
 {
 
   /**
    * Sessions with pending messages (!) are kept in a DLL.
    */
-  struct Session *next;
+  struct GNUNET_ATS_Session *next;
 
   /**
    * Sessions with pending messages (!) are kept in a DLL.
    */
-  struct Session *prev;
+  struct GNUNET_ATS_Session *prev;
 
   /**
    * To whom are we talking to (set to our identity
@@ -218,7 +218,7 @@ struct Session
   /**
    * Session timeout task.
    */
-  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+  struct GNUNET_SCHEDULER_Task * timeout_task;
 
   /**
    * Number of messages we currently have in our write queue.
@@ -243,13 +243,6 @@ struct UNIX_Sock_Info
    * The network handle
    */
   struct GNUNET_NETWORK_Handle *desc;
-
-  /**
-   * The port we bound to (not an actual PORT, as UNIX domain sockets
-   * don't have ports, but rather a number in the path name to make this
-   * one unique).
-   */
-  uint16_t port;
 };
 
 
@@ -262,17 +255,17 @@ struct Plugin
   /**
    * ID of task used to update our addresses when one expires.
    */
-  GNUNET_SCHEDULER_TaskIdentifier address_update_task;
+  struct GNUNET_SCHEDULER_Task * address_update_task;
 
   /**
    * ID of read task
    */
-  GNUNET_SCHEDULER_TaskIdentifier read_task;
+  struct GNUNET_SCHEDULER_Task * read_task;
 
   /**
    * ID of write task
    */
-  GNUNET_SCHEDULER_TaskIdentifier write_task;
+  struct GNUNET_SCHEDULER_Task * write_task;
 
   /**
    * Number of bytes we currently have in our write queues.
@@ -285,7 +278,7 @@ struct Plugin
   struct GNUNET_TRANSPORT_PluginEnvironment *env;
 
   /**
-   * Sessions (map from peer identity to `struct Session`)
+   * Sessions (map from peer identity to `struct GNUNET_ATS_Session`)
    */
   struct GNUNET_CONTAINER_MultiPeerMap *session_map;
 
@@ -300,7 +293,7 @@ struct Plugin
   struct UNIXMessageWrapper *msg_tail;
 
   /**
-   * Path of our unix domain socket (/tmp/unix-plugin-PORT)
+   * Path of our unix domain socket (/tmp/unix-plugin)
    */
   char *unix_socket_path;
 
@@ -324,11 +317,6 @@ struct Plugin
    */
   uint32_t myoptions;
 
-  /**
-   * ATS network
-   */
-  struct GNUNET_ATS_Information ats_network;
-
   /**
    * Are we using an abstract UNIX domain socket?
    */
@@ -347,7 +335,7 @@ struct Plugin
  */
 static void
 notify_session_monitor (struct Plugin *plugin,
-                        struct Session *session,
+                        struct GNUNET_ATS_Session *session,
                         enum GNUNET_TRANSPORT_SessionState state)
 {
   struct GNUNET_TRANSPORT_SessionInfo info;
@@ -382,9 +370,9 @@ notify_session_monitor (struct Plugin *plugin,
  * @return string representing the same address
  */
 static const char *
-unix_address_to_string (void *cls,
-                        const void *addr,
-                        size_t addrlen)
+unix_plugin_address_to_string (void *cls,
+                               const void *addr,
+                               size_t addrlen)
 {
   static char rbuf[1024];
   struct UnixAddress *ua = (struct UnixAddress *) addr;
@@ -442,8 +430,8 @@ unix_address_to_string (void *cls,
  * @return #GNUNET_OK on success
  */
 static int
-unix_session_disconnect (void *cls,
-                         struct Session *session)
+unix_plugin_session_disconnect (void *cls,
+                                struct GNUNET_ATS_Session *session)
 {
   struct Plugin *plugin = cls;
   struct UNIXMessageWrapper *msgw;
@@ -452,9 +440,9 @@ unix_session_disconnect (void *cls,
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Disconnecting session for peer `%s' `%s'\n",
        GNUNET_i2s (&session->target),
-       unix_address_to_string (NULL,
-                               session->address->address,
-                               session->address->address_length));
+       unix_plugin_address_to_string (NULL,
+                                      session->address->address,
+                                      session->address->address_length));
   plugin->env->session_end (plugin->env->cls,
                             session->address,
                             session);
@@ -489,15 +477,15 @@ unix_session_disconnect (void *cls,
                         "# UNIX sessions active",
                         GNUNET_CONTAINER_multipeermap_size (plugin->session_map),
                         GNUNET_NO);
-  if (GNUNET_SCHEDULER_NO_TASK != session->timeout_task)
+  if (NULL != session->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (session->timeout_task);
-    session->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+    session->timeout_task = NULL;
     session->timeout = GNUNET_TIME_UNIT_ZERO_ABS;
   }
   notify_session_monitor (plugin,
                           session,
-                          GNUNET_TRANSPORT_SS_DOWN);
+                          GNUNET_TRANSPORT_SS_DONE);
   GNUNET_HELLO_address_free (session->address);
   GNUNET_break (0 == session->bytes_in_queue);
   GNUNET_break (0 == session->msgs_in_queue);
@@ -509,36 +497,34 @@ unix_session_disconnect (void *cls,
 /**
  * Session was idle for too long, so disconnect it
  *
- * @param cls the `struct Session *` to disconnect
- * @param tc scheduler context
+ * @param cls the `struct GNUNET_ATS_Session *` to disconnect
  */
 static void
-session_timeout (void *cls,
-                const struct GNUNET_SCHEDULER_TaskContext *tc)
+session_timeout (void *cls)
 {
-  struct Session *session = cls;
+  struct GNUNET_ATS_Session *session = cls;
   struct GNUNET_TIME_Relative left;
 
-  session->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  session->timeout_task = NULL;
   left = GNUNET_TIME_absolute_get_remaining (session->timeout);
   if (0 != left.rel_value_us)
-    {
-      /* not actually our turn yet, but let's at least update
-         the monitor, it may think we're about to die ... */
-      notify_session_monitor (session->plugin,
-                              session,
-                              GNUNET_TRANSPORT_SS_UP);
-      session->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
-                                                            &session_timeout,
-                                                            session);
-      return;
-    }
+  {
+    /* not actually our turn yet, but let's at least update
+       the monitor, it may think we're about to die ... */
+    notify_session_monitor (session->plugin,
+                            session,
+                            GNUNET_TRANSPORT_SS_UPDATE);
+    session->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
+                                                          &session_timeout,
+                                                          session);
+    return;
+  }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Session %p was idle for %s, disconnecting\n",
        session,
        GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                               GNUNET_YES));
-  unix_session_disconnect (session->plugin, session);
+  unix_plugin_session_disconnect (session->plugin, session);
 }
 
 
@@ -550,9 +536,9 @@ session_timeout (void *cls,
  * @param session session for which the timeout should be rescheduled
  */
 static void
-reschedule_session_timeout (struct Session *session)
+reschedule_session_timeout (struct GNUNET_ATS_Session *session)
 {
-  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != session->timeout_task);
+  GNUNET_assert (NULL != session->timeout_task);
   session->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
 }
 
@@ -561,7 +547,7 @@ reschedule_session_timeout (struct Session *session)
  * Convert unix path to a `struct sockaddr_un *`
  *
  * @param unixpath path to convert
- * @param sock_len[out] set to the length of the address
+ * @param[out] sock_len set to the length of the address
  * @return converted unix path
  */
 static struct sockaddr_un *
@@ -577,10 +563,10 @@ unix_address_to_sockaddr (const char *unixpath,
   slen = strlen (unixpath);
   if (slen >= sizeof (un->sun_path))
     slen = sizeof (un->sun_path) - 1;
-  memcpy (un->sun_path, unixpath, slen);
+  GNUNET_memcpy (un->sun_path, unixpath, slen);
   un->sun_path[slen] = '\0';
   slen = sizeof (struct sockaddr_un);
-#if HAVE_SOCKADDR_IN_SIN_LEN
+#if HAVE_SOCKADDR_UN_SUN_LEN
   un->sun_len = (u_char) slen;
 #endif
   (*sock_len) = slen;
@@ -596,7 +582,7 @@ struct LookupCtx
   /**
    * Location to store the session, if found.
    */
-  struct Session *res;
+  struct GNUNET_ATS_Session *res;
 
   /**
    * Address we are looking for.
@@ -619,7 +605,7 @@ lookup_session_it (void *cls,
                   void *value)
 {
   struct LookupCtx *lctx = cls;
-  struct Session *session = value;
+  struct GNUNET_ATS_Session *session = value;
 
   if (0 == GNUNET_HELLO_address_cmp (lctx->address,
                                      session->address))
@@ -638,7 +624,7 @@ lookup_session_it (void *cls,
  * @param address the address to find
  * @return NULL if session was not found
  */
-static struct Session *
+static struct GNUNET_ATS_Session *
 lookup_session (struct Plugin *plugin,
                 const struct GNUNET_HELLO_Address *address)
 {
@@ -662,7 +648,7 @@ lookup_session (struct Plugin *plugin,
  * @return keepalive factor
  */
 static unsigned int
-unix_query_keepalive_factor (void *cls)
+unix_plugin_query_keepalive_factor (void *cls)
 {
   return 3;
 }
@@ -807,12 +793,28 @@ resend:
  * @param session the session
  * @return the network type in HBO or #GNUNET_SYSERR
  */
-static enum GNUNET_ATS_Network_Type
-unix_get_network (void *cls,
-                 struct Session *session)
+static enum GNUNET_NetworkType
+unix_plugin_get_network (void *cls,
+                         struct GNUNET_ATS_Session *session)
 {
   GNUNET_assert (NULL != session);
-  return GNUNET_ATS_NET_LOOPBACK;
+  return GNUNET_NT_LOOPBACK;
+}
+
+
+/**
+ * Function obtain the network type for a session
+ *
+ * @param cls closure (`struct Plugin *`)
+ * @param address the address
+ * @return the network type
+ */
+static enum GNUNET_NetworkType
+unix_plugin_get_network_for_address (void *cls,
+                                     const struct GNUNET_HELLO_Address *address)
+
+{
+  return GNUNET_NT_LOOPBACK;
 }
 
 
@@ -824,12 +826,12 @@ unix_get_network (void *cls,
  * @param address the address
  * @return the session or NULL of max connections exceeded
  */
-static struct Session *
+static struct GNUNET_ATS_Session *
 unix_plugin_get_session (void *cls,
                         const struct GNUNET_HELLO_Address *address)
 {
   struct Plugin *plugin = cls;
-  struct Session *session;
+  struct GNUNET_ATS_Session *session;
   struct UnixAddress *ua;
   char * addrstr;
   uint32_t addr_str_len;
@@ -875,26 +877,27 @@ unix_plugin_get_session (void *cls,
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Found existing session %p for address `%s'\n",
         session,
-        unix_address_to_string (NULL,
-                                 address->address,
-                                 address->address_length));
+        unix_plugin_address_to_string (NULL,
+                                        address->address,
+                                        address->address_length));
     return session;
   }
 
   /* create a new session */
-  session = GNUNET_new (struct Session);
+  session = GNUNET_new (struct GNUNET_ATS_Session);
   session->target = address->peer;
   session->address = GNUNET_HELLO_address_copy (address);
   session->plugin = plugin;
+  session->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
   session->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                                         &session_timeout,
                                                         session);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Creating a new session %p for address `%s'\n",
        session,
-       unix_address_to_string (NULL,
-                               address->address,
-                               address->address_length));
+       unix_plugin_address_to_string (NULL,
+                                      address->address,
+                                      address->address_length));
   (void) GNUNET_CONTAINER_multipeermap_put (plugin->session_map,
                                            &address->peer, session,
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -902,6 +905,9 @@ unix_plugin_get_session (void *cls,
                         "# UNIX sessions active",
                         GNUNET_CONTAINER_multipeermap_size (plugin->session_map),
                         GNUNET_NO);
+  notify_session_monitor (plugin,
+                          session,
+                          GNUNET_TRANSPORT_SS_INIT);
   notify_session_monitor (plugin,
                           session,
                           GNUNET_TRANSPORT_SS_UP);
@@ -921,7 +927,7 @@ unix_plugin_get_session (void *cls,
 static void
 unix_plugin_update_session_timeout (void *cls,
                                     const struct GNUNET_PeerIdentity *peer,
-                                    struct Session *session)
+                                    struct GNUNET_ATS_Session *session)
 {
   struct Plugin *plugin = cls;
 
@@ -950,16 +956,16 @@ static void
 unix_demultiplexer (struct Plugin *plugin,
                     struct GNUNET_PeerIdentity *sender,
                     const struct GNUNET_MessageHeader *currhdr,
-                    const struct UnixAddress *ua, size_t ua_len)
+                    const struct UnixAddress *ua,
+                    size_t ua_len)
 {
-  struct Session *session;
+  struct GNUNET_ATS_Session *session;
   struct GNUNET_HELLO_Address *address;
 
-  GNUNET_break (ntohl(plugin->ats_network.value) != GNUNET_ATS_NET_UNSPECIFIED);
   GNUNET_assert (ua_len >= sizeof (struct UnixAddress));
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received message from %s\n",
-       unix_address_to_string (NULL, ua, ua_len));
+       unix_plugin_address_to_string (NULL, ua, ua_len));
   GNUNET_STATISTICS_update (plugin->env->stats,
                            "# bytes received via UNIX",
                            ntohs (currhdr->size),
@@ -978,10 +984,7 @@ unix_demultiplexer (struct Plugin *plugin,
     plugin->env->session_start (NULL,
                                 session->address,
                                 session,
-                                &plugin->ats_network, 1);
-    notify_session_monitor (plugin,
-                            session,
-                            GNUNET_TRANSPORT_SS_UP);
+                                GNUNET_NT_LOOPBACK);
   }
   else
   {
@@ -992,10 +995,6 @@ unix_demultiplexer (struct Plugin *plugin,
                         session->address,
                         session,
                         currhdr);
-  plugin->env->update_address_metrics (plugin->env->cls,
-                                       session->address,
-                                       session,
-                                      &plugin->ats_network, 1);
 }
 
 
@@ -1055,7 +1054,7 @@ unix_plugin_do_read (struct Plugin *plugin)
   ua_len = sizeof (struct UnixAddress) + strlen (un.sun_path) + 1;
   ua = GNUNET_malloc (ua_len);
   ua->addrlen = htonl (strlen (&un.sun_path[0]) +1);
-  memcpy (&ua[1], &un.sun_path[0], strlen (un.sun_path) + 1);
+  GNUNET_memcpy (&ua[1], &un.sun_path[0], strlen (un.sun_path) + 1);
   if (is_abstract)
     ua->options = htonl(UNIX_OPTIONS_USE_ABSTRACT_SOCKETS);
   else
@@ -1070,7 +1069,7 @@ unix_plugin_do_read (struct Plugin *plugin)
     return;
   }
   msgbuf = (char *) &msg[1];
-  memcpy (&sender,
+  GNUNET_memcpy (&sender,
           &msg->sender,
           sizeof (struct GNUNET_PeerIdentity));
   offset = 0;
@@ -1095,16 +1094,17 @@ unix_plugin_do_read (struct Plugin *plugin)
 /**
  * Write to UNIX domain socket (it is ready).
  *
- * @param session session to write data for
+ * @param plugin handle to the plugin
  */
 static void
 unix_plugin_do_write (struct Plugin *plugin)
 {
   ssize_t sent = 0;
   struct UNIXMessageWrapper *msgw;
-  struct Session *session;
+  struct GNUNET_ATS_Session *session;
   int did_delete;
 
+  session = NULL;
   did_delete = GNUNET_NO;
   while (NULL != (msgw = plugin->msg_head))
   {
@@ -1146,13 +1146,13 @@ unix_plugin_do_write (struct Plugin *plugin)
     if (GNUNET_YES == did_delete)
       notify_session_monitor (plugin,
                               session,
-                              GNUNET_TRANSPORT_SS_UP);
+                              GNUNET_TRANSPORT_SS_UPDATE);
     return; /* Nothing to send at the moment */
   }
-
+  session = msgw->session;
   sent = unix_real_send (plugin,
                          plugin->unix_sock.desc,
-                         &msgw->session->target,
+                         &session->target,
                          (const char *) msgw->msg,
                          msgw->msgsize,
                          msgw->priority,
@@ -1168,13 +1168,12 @@ unix_plugin_do_write (struct Plugin *plugin)
                              1, GNUNET_NO);
     notify_session_monitor (plugin,
                             session,
-                            GNUNET_TRANSPORT_SS_UP);
+                            GNUNET_TRANSPORT_SS_UPDATE);
     return;
   }
   GNUNET_CONTAINER_DLL_remove (plugin->msg_head,
                                plugin->msg_tail,
                                msgw);
-  session = msgw->session;
   session->msgs_in_queue--;
   GNUNET_assert (session->bytes_in_queue >= msgw->msgsize);
   session->bytes_in_queue -= msgw->msgsize;
@@ -1185,7 +1184,7 @@ unix_plugin_do_write (struct Plugin *plugin)
                          plugin->bytes_in_queue, GNUNET_NO);
   notify_session_monitor (plugin,
                           session,
-                          GNUNET_TRANSPORT_SS_UP);
+                          GNUNET_TRANSPORT_SS_UPDATE);
   if (GNUNET_SYSERR == sent)
   {
     /* failed and no retry */
@@ -1224,17 +1223,15 @@ unix_plugin_do_write (struct Plugin *plugin)
  * Then reschedule this function to be called again once more is available.
  *
  * @param cls the plugin handle
- * @param tc the scheduling context
  */
 static void
-unix_plugin_select_read (void *cls,
-                         const struct GNUNET_SCHEDULER_TaskContext *tc)
+unix_plugin_select_read (void *cls)
 {
   struct Plugin *plugin = cls;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
 
-  plugin->read_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
+  plugin->read_task = NULL;
+  tc = GNUNET_SCHEDULER_get_task_context ();
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
     unix_plugin_do_read (plugin);
   plugin->read_task =
@@ -1249,17 +1246,15 @@ unix_plugin_select_read (void *cls,
  * Then reschedule this function to be called again once more is available.
  *
  * @param cls the plugin handle
- * @param tc the scheduling context
  */
 static void
-unix_plugin_select_write (void *cls,
-                         const struct GNUNET_SCHEDULER_TaskContext *tc)
+unix_plugin_select_write (void *cls)
 {
   struct Plugin *plugin = cls;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
 
-  plugin->write_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
+  plugin->write_task = NULL;
+  tc = GNUNET_SCHEDULER_get_task_context ();
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))
     unix_plugin_do_write (plugin);
   if (NULL == plugin->msg_head)
@@ -1300,7 +1295,7 @@ unix_plugin_select_write (void *cls,
  */
 static ssize_t
 unix_plugin_send (void *cls,
-                  struct Session *session,
+                  struct GNUNET_ATS_Session *session,
                   const char *msgbuf,
                   size_t msgbuf_size,
                   unsigned int priority,
@@ -1321,9 +1316,9 @@ unix_plugin_send (void *cls,
     LOG (GNUNET_ERROR_TYPE_ERROR,
         "Invalid session for peer `%s' `%s'\n",
         GNUNET_i2s (&session->target),
-        unix_address_to_string(NULL,
-                                session->address->address,
-                                session->address->address_length));
+        unix_plugin_address_to_string (NULL,
+                                        session->address->address,
+                                        session->address->address_length));
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
@@ -1331,16 +1326,16 @@ unix_plugin_send (void *cls,
        "Sending %u bytes with session for peer `%s' `%s'\n",
        msgbuf_size,
        GNUNET_i2s (&session->target),
-       unix_address_to_string (NULL,
-                               session->address->address,
-                               session->address->address_length));
+       unix_plugin_address_to_string (NULL,
+                                      session->address->address,
+                                      session->address->address_length));
   ssize = sizeof (struct UNIXMessage) + msgbuf_size;
   message = GNUNET_malloc (sizeof (struct UNIXMessage) + msgbuf_size);
   message->header.size = htons (ssize);
   message->header.type = htons (0);
-  memcpy (&message->sender, plugin->env->my_identity,
+  GNUNET_memcpy (&message->sender, plugin->env->my_identity,
           sizeof (struct GNUNET_PeerIdentity));
-  memcpy (&message[1], msgbuf, msgbuf_size);
+  GNUNET_memcpy (&message[1], msgbuf, msgbuf_size);
   wrapper = GNUNET_new (struct UNIXMessageWrapper);
   wrapper->msg = message;
   wrapper->msgsize = ssize;
@@ -1363,8 +1358,8 @@ unix_plugin_send (void *cls,
                         GNUNET_NO);
   notify_session_monitor (plugin,
                           session,
-                          GNUNET_TRANSPORT_SS_UP);
-  if (GNUNET_SCHEDULER_NO_TASK == plugin->write_task)
+                          GNUNET_TRANSPORT_SS_UPDATE);
+  if (NULL == plugin->write_task)
     plugin->write_task =
       GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
                                       plugin->unix_sock.desc,
@@ -1393,12 +1388,12 @@ unix_transport_server_start (void *cls)
     plugin->unix_socket_path[0] = '@';
     un->sun_path[0] = '\0';
   }
-  plugin->ats_network = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) un, un_len);
   plugin->unix_sock.desc =
       GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
   if (NULL == plugin->unix_sock.desc)
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
+    GNUNET_free (un);
     return GNUNET_SYSERR;
   }
   if ('\0' != un->sun_path[0])
@@ -1418,6 +1413,8 @@ unix_transport_server_start (void *cls)
                                   (const struct sockaddr *) un, un_len))
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
+    LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot bind to `%s'\n"),
+        un->sun_path);
     GNUNET_NETWORK_socket_close (plugin->unix_sock.desc);
     plugin->unix_sock.desc = NULL;
     GNUNET_free (un);
@@ -1452,9 +1449,9 @@ unix_transport_server_start (void *cls)
  *
  */
 static int
-unix_check_address (void *cls,
-                    const void *addr,
-                    size_t addrlen)
+unix_plugin_check_address (void *cls,
+                           const void *addr,
+                           size_t addrlen)
 {
   struct Plugin* plugin = cls;
   const struct UnixAddress *ua = addr;
@@ -1513,9 +1510,9 @@ unix_plugin_address_pretty_printer (void *cls, const char *type,
   const char *ret;
 
   if ( (NULL != addr) && (addrlen > 0))
-    ret = unix_address_to_string (NULL,
-                                  addr,
-                                  addrlen);
+    ret = unix_plugin_address_to_string (NULL,
+                                         addr,
+                                         addrlen);
   else
     ret = NULL;
   asc (asc_cls,
@@ -1538,10 +1535,10 @@ unix_plugin_address_pretty_printer (void *cls, const char *type,
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
  */
 static int
-unix_string_to_address (void *cls,
-                        const char *addr,
-                        uint16_t addrlen,
-                        void **buf, size_t *added)
+unix_plugin_string_to_address (void *cls,
+                               const char *addr,
+                               uint16_t addrlen,
+                               void **buf, size_t *added)
 {
   struct UnixAddress *ua;
   char *address;
@@ -1601,7 +1598,7 @@ unix_string_to_address (void *cls,
   ua = GNUNET_malloc (ua_size);
   ua->options = htonl (options);
   ua->addrlen = htonl (strlen (address) + 1);
-  memcpy (&ua[1], address, strlen (address) + 1);
+  GNUNET_memcpy (&ua[1], address, strlen (address) + 1);
   GNUNET_free (plugin);
 
   (*buf) = ua;
@@ -1614,11 +1611,9 @@ unix_string_to_address (void *cls,
  * Notify transport service about address
  *
  * @param cls the plugin
- * @param tc unused
  */
 static void
-address_notification (void *cls,
-                     const struct GNUNET_SCHEDULER_TaskContext *tc)
+address_notification (void *cls)
 {
   struct Plugin *plugin = cls;
   struct GNUNET_HELLO_Address *address;
@@ -1631,9 +1626,9 @@ address_notification (void *cls,
   ua->options = htonl (plugin->myoptions);
   ua->addrlen = htonl(strlen (plugin->unix_socket_path) + 1);
   unix_path = (char *) &ua[1];
-  memcpy (unix_path, plugin->unix_socket_path, strlen (plugin->unix_socket_path) + 1);
+  GNUNET_memcpy (unix_path, plugin->unix_socket_path, strlen (plugin->unix_socket_path) + 1);
 
-  plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK;
+  plugin->address_update_task = NULL;
   address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
                                            PLUGIN_NAME,
                                            ua,
@@ -1652,7 +1647,7 @@ address_notification (void *cls,
  *
  * @param cls the plugin
  * @param key peer identity (unused)
- * @param value the `struct Session *` to disconnect
+ * @param value the `struct GNUNET_ATS_Session *` to disconnect
  * @return #GNUNET_YES (always, continue to iterate)
  */
 static int
@@ -1661,9 +1656,9 @@ get_session_delete_it (void *cls,
                       void *value)
 {
   struct Plugin *plugin = cls;
-  struct Session *s = value;
+  struct GNUNET_ATS_Session *session = value;
 
-  unix_session_disconnect (plugin, s);
+  unix_plugin_session_disconnect (plugin, session);
   return GNUNET_YES;
 }
 
@@ -1676,12 +1671,11 @@ get_session_delete_it (void *cls,
  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the operation failed
  */
 static void
-unix_peer_disconnect (void *cls,
-                      const struct GNUNET_PeerIdentity *target)
+unix_plugin_peer_disconnect (void *cls,
+                             const struct GNUNET_PeerIdentity *target)
 {
   struct Plugin *plugin = cls;
 
-  GNUNET_assert (NULL != plugin);
   GNUNET_CONTAINER_multipeermap_get_multiple (plugin->session_map,
                                              target,
                                              &get_session_delete_it, plugin);
@@ -1694,7 +1688,7 @@ unix_peer_disconnect (void *cls,
  *
  * @param cls the `struct Plugin` with the monitor callback (`sic`)
  * @param peer peer we send information about
- * @param value our `struct Session` to send information about
+ * @param value our `struct GNUNET_ATS_Session` to send information about
  * @return #GNUNET_OK (continue to iterate)
  */
 static int
@@ -1703,8 +1697,11 @@ send_session_info_iter (void *cls,
                         void *value)
 {
   struct Plugin *plugin = cls;
-  struct Session *session = value;
+  struct GNUNET_ATS_Session *session = value;
 
+  notify_session_monitor (plugin,
+                          session,
+                          GNUNET_TRANSPORT_SS_INIT);
   notify_session_monitor (plugin,
                           session,
                           GNUNET_TRANSPORT_SS_UP);
@@ -1725,18 +1722,22 @@ send_session_info_iter (void *cls,
  * @param sic_cls closure for @a sic
  */
 static void
-unix_setup_monitor (void *cls,
-                    GNUNET_TRANSPORT_SessionInfoCallback sic,
-                    void *sic_cls)
+unix_plugin_setup_monitor (void *cls,
+                           GNUNET_TRANSPORT_SessionInfoCallback sic,
+                           void *sic_cls)
 {
   struct Plugin *plugin = cls;
 
   plugin->sic = sic;
   plugin->sic_cls = sic_cls;
   if (NULL != sic)
+  {
     GNUNET_CONTAINER_multipeermap_iterate (plugin->session_map,
                                            &send_session_info_iter,
                                            plugin);
+    /* signal end of first iteration */
+    sic (sic_cls, NULL, NULL);
+  }
 }
 
 
@@ -1762,8 +1763,8 @@ libgnunet_plugin_transport_unix_init (void *cls)
     api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions);
     api->cls = NULL;
     api->address_pretty_printer = &unix_plugin_address_pretty_printer;
-    api->address_to_string = &unix_address_to_string;
-    api->string_to_address = &unix_string_to_address;
+    api->address_to_string = &unix_plugin_address_to_string;
+    api->string_to_address = &unix_plugin_string_to_address;
     return api;
   }
 
@@ -1797,16 +1798,17 @@ libgnunet_plugin_transport_unix_init (void *cls)
   api->cls = plugin;
   api->get_session = &unix_plugin_get_session;
   api->send = &unix_plugin_send;
-  api->disconnect_peer = &unix_peer_disconnect;
-  api->disconnect_session = &unix_session_disconnect;
-  api->query_keepalive_factor = &unix_query_keepalive_factor;
+  api->disconnect_peer = &unix_plugin_peer_disconnect;
+  api->disconnect_session = &unix_plugin_session_disconnect;
+  api->query_keepalive_factor = &unix_plugin_query_keepalive_factor;
   api->address_pretty_printer = &unix_plugin_address_pretty_printer;
-  api->address_to_string = &unix_address_to_string;
-  api->check_address = &unix_check_address;
-  api->string_to_address = &unix_string_to_address;
-  api->get_network = &unix_get_network;
+  api->address_to_string = &unix_plugin_address_to_string;
+  api->check_address = &unix_plugin_check_address;
+  api->string_to_address = &unix_plugin_string_to_address;
+  api->get_network = &unix_plugin_get_network;
+  api->get_network_for_address = &unix_plugin_get_network_for_address;
   api->update_session_timeout = &unix_plugin_update_session_timeout;
-  api->setup_monitor = &unix_setup_monitor;
+  api->setup_monitor = &unix_plugin_setup_monitor;
   sockets_created = unix_transport_server_start (plugin);
   if ((0 == sockets_created) || (GNUNET_SYSERR == sockets_created))
   {
@@ -1839,7 +1841,7 @@ libgnunet_plugin_transport_unix_done (void *cls)
   struct UNIXMessageWrapper * msgw;
   struct UnixAddress *ua;
   size_t len;
-  struct Session *session;
+  struct GNUNET_ATS_Session *session;
 
   if (NULL == plugin)
   {
@@ -1850,7 +1852,7 @@ libgnunet_plugin_transport_unix_done (void *cls)
   ua = GNUNET_malloc (len);
   ua->options = htonl (plugin->myoptions);
   ua->addrlen = htonl(strlen (plugin->unix_socket_path) + 1);
-  memcpy (&ua[1],
+  GNUNET_memcpy (&ua[1],
           plugin->unix_socket_path,
           strlen (plugin->unix_socket_path) + 1);
   address = GNUNET_HELLO_address_allocate (plugin->env->my_identity,
@@ -1884,20 +1886,20 @@ libgnunet_plugin_transport_unix_done (void *cls)
     GNUNET_free (msgw);
   }
 
-  if (GNUNET_SCHEDULER_NO_TASK != plugin->read_task)
+  if (NULL != plugin->read_task)
   {
     GNUNET_SCHEDULER_cancel (plugin->read_task);
-    plugin->read_task = GNUNET_SCHEDULER_NO_TASK;
+    plugin->read_task = NULL;
   }
-  if (GNUNET_SCHEDULER_NO_TASK != plugin->write_task)
+  if (NULL != plugin->write_task)
   {
     GNUNET_SCHEDULER_cancel (plugin->write_task);
-    plugin->write_task = GNUNET_SCHEDULER_NO_TASK;
+    plugin->write_task = NULL;
   }
-  if (GNUNET_SCHEDULER_NO_TASK != plugin->address_update_task)
+  if (NULL != plugin->address_update_task)
   {
     GNUNET_SCHEDULER_cancel (plugin->address_update_task);
-    plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK;
+    plugin->address_update_task = NULL;
   }
   if (NULL != plugin->unix_sock.desc)
   {