Avoid trying to disconnect a neighbour twice
[oweals/gnunet.git] / src / transport / plugin_transport_unix.c
index 5cf9c54325094a801ec34a50b90f6f9673f6740e..1866c56a445cc6015496d72a32fa0c2b954cdd70 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     (C) 2010-2014 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2010-2014 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
@@ -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.
@@ -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?
    */
@@ -489,15 +477,15 @@ unix_plugin_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);
@@ -519,7 +507,7 @@ session_timeout (void *cls,
   struct 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)
   {
@@ -527,7 +515,7 @@ session_timeout (void *cls,
        the monitor, it may think we're about to die ... */
     notify_session_monitor (session->plugin,
                             session,
-                            GNUNET_TRANSPORT_SS_UP);
+                            GNUNET_TRANSPORT_SS_UPDATE);
     session->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
                                                           &session_timeout,
                                                           session);
@@ -552,7 +540,7 @@ session_timeout (void *cls,
 static void
 reschedule_session_timeout (struct 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 +549,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 *
@@ -903,6 +891,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);
@@ -951,12 +942,12 @@ 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_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",
@@ -979,10 +970,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_ATS_NET_LOOPBACK);
   }
   else
   {
@@ -993,10 +981,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);
 }
 
 
@@ -1096,7 +1080,7 @@ 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)
@@ -1148,13 +1132,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,
@@ -1170,13 +1154,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;
@@ -1187,7 +1170,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 */
@@ -1234,7 +1217,7 @@ unix_plugin_select_read (void *cls,
 {
   struct Plugin *plugin = cls;
 
-  plugin->read_task = GNUNET_SCHEDULER_NO_TASK;
+  plugin->read_task = NULL;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
@@ -1259,7 +1242,7 @@ unix_plugin_select_write (void *cls,
 {
   struct Plugin *plugin = cls;
 
-  plugin->write_task = GNUNET_SCHEDULER_NO_TASK;
+  plugin->write_task = NULL;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))
@@ -1365,8 +1348,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,
@@ -1395,12 +1378,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])
@@ -1420,6 +1403,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);
@@ -1635,7 +1620,7 @@ address_notification (void *cls,
   unix_path = (char *) &ua[1];
   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,
@@ -1706,6 +1691,9 @@ send_session_info_iter (void *cls,
   struct Plugin *plugin = cls;
   struct Session *session = value;
 
+  notify_session_monitor (plugin,
+                          session,
+                          GNUNET_TRANSPORT_SS_INIT);
   notify_session_monitor (plugin,
                           session,
                           GNUNET_TRANSPORT_SS_UP);
@@ -1889,20 +1877,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)
   {