gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r32815 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r32815 - gnunet/src/transport
Date: Thu, 27 Mar 2014 17:51:32 +0100

Author: wachs
Date: 2014-03-27 17:51:32 +0100 (Thu, 27 Mar 2014)
New Revision: 32815

Modified:
   gnunet/src/transport/gnunet-service-transport_clients.c
   gnunet/src/transport/gnunet-service-transport_neighbours.c
   gnunet/src/transport/gnunet-transport.c
   gnunet/src/transport/transport.h
   gnunet/src/transport/transport_api.c
Log:
added functionality to use the CLI to disconnect peers
fixed DISCONNECT functionality


Modified: gnunet/src/transport/gnunet-service-transport_clients.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_clients.c     2014-03-27 
15:03:17 UTC (rev 32814)
+++ gnunet/src/transport/gnunet-service-transport_clients.c     2014-03-27 
16:51:32 UTC (rev 32815)
@@ -794,27 +794,59 @@
   const struct TransportRequestConnectMessage *trcm =
       (const struct TransportRequestConnectMessage *) message;
 
-  GNUNET_STATISTICS_update (GST_stats,
-                            gettext_noop
-                            ("# REQUEST CONNECT messages received"), 1,
-                            GNUNET_NO);
+  if (GNUNET_YES == ntohl (trcm->connect))
+  {
+    GNUNET_STATISTICS_update (GST_stats,
+                              gettext_noop
+                              ("# REQUEST CONNECT messages received"), 1,
+                              GNUNET_NO);
 
-  if (0 == memcmp (&trcm->peer, &GST_my_identity,
-               sizeof (struct GNUNET_PeerIdentity)))
+    if (0 == memcmp (&trcm->peer, &GST_my_identity,
+                  sizeof (struct GNUNET_PeerIdentity)))
+    {
+      GNUNET_break_op (0);
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Received a request connect message myself `%s'\n",
+                  GNUNET_i2s (&trcm->peer));
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  _("Received a request connect message for peer `%s'\n"),
+                  GNUNET_i2s (&trcm->peer));
+
+      (void) GST_blacklist_test_allowed (&trcm->peer, NULL, 
&try_connect_if_allowed,
+                                       NULL);
+    }
+  }
+  else if (GNUNET_NO == ntohl (trcm->connect))
   {
-    GNUNET_break_op (0);
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Received a request connect message myself `%s'\n",
-                GNUNET_i2s (&trcm->peer));
+    GNUNET_STATISTICS_update (GST_stats,
+                              gettext_noop
+                              ("# REQUEST DISCONNECT messages received"), 1,
+                              GNUNET_NO);
+
+    if (0 == memcmp (&trcm->peer, &GST_my_identity,
+                  sizeof (struct GNUNET_PeerIdentity)))
+    {
+      GNUNET_break_op (0);
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Received a request disconnect message myself `%s'\n",
+                  GNUNET_i2s (&trcm->peer));
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  _("Received a request disconnect message for peer `%s'\n"),
+                  GNUNET_i2s (&trcm->peer));
+      (void) GST_neighbours_force_disconnect (&trcm->peer);
+    }
   }
   else
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Received a request connect message for peer `%s'\n"),
-                GNUNET_i2s (&trcm->peer));
-
-    (void) GST_blacklist_test_allowed (&trcm->peer, NULL, 
&try_connect_if_allowed,
-                                     NULL);
+    GNUNET_break_op (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
   }
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }

Modified: gnunet/src/transport/gnunet-service-transport_neighbours.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_neighbours.c  2014-03-27 
15:03:17 UTC (rev 32814)
+++ gnunet/src/transport/gnunet-service-transport_neighbours.c  2014-03-27 
16:51:32 UTC (rev 32815)
@@ -46,7 +46,7 @@
  * Time we give plugin to transmit DISCONNECT message before the
  * neighbour entry self-destructs.
  */
-#define DISCONNECT_SENT_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MILLISECONDS, 100)
+#define DISCONNECT_SENT_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MILLISECONDS, 500)
 
 /**
  * How often must a peer violate bandwidth quotas before we start
@@ -1054,7 +1054,7 @@
 {
   struct SessionDisconnectMessage disconnect_msg;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Sending DISCONNECT message to peer `%4s'\n",
               GNUNET_i2s (&n->id));
   disconnect_msg.header.size = htons (sizeof (struct 
SessionDisconnectMessage));
@@ -1075,10 +1075,9 @@
                                          &disconnect_msg.purpose,
                                          &disconnect_msg.signature));
 
-  (void) send_with_session (n,
-                           (const char *) &disconnect_msg, sizeof 
(disconnect_msg),
-                           UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL,
-                           GNUNET_NO, &send_disconnect_cont, NULL);
+  (void) send_with_session (n, (const char *) &disconnect_msg,
+      sizeof (disconnect_msg), UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL,
+      GNUNET_NO, &send_disconnect_cont, NULL );
   GNUNET_STATISTICS_update (GST_stats,
                             gettext_noop
                             ("# DISCONNECT messages sent"), 1,
@@ -1113,7 +1112,6 @@
     break;
   case GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS:
     /* we never ACK'ed the other peer's request, no need to send DISCONNECT */
-    set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED);
     free_neighbour (n, GNUNET_NO);
     return;
   case GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK:
@@ -1121,6 +1119,7 @@
     send_disconnect (n);
     set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT);
     break;
+  case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
   case GNUNET_TRANSPORT_PS_CONNECTED:
   case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
     /* we are currently connected, need to send disconnect and do
@@ -1134,13 +1133,9 @@
     set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT);
     break;
   case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
-    /* ATS address request timeout, disconnect without sending disconnect 
message */
-    GNUNET_STATISTICS_set (GST_stats,
-                           gettext_noop ("# peers connected"),
-                           --neighbours_connected,
-                           GNUNET_NO);
-    disconnect_notify_cb (callback_cls, &n->id);
-    set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT);
+    /* Disconnecting while waiting for an ATS address to reconnect,
+     * cannot send DISCONNECT */
+    free_neighbour (n, GNUNET_NO);
     break;
   case GNUNET_TRANSPORT_PS_DISCONNECT:
     /* already disconnected, ignore */
@@ -1680,7 +1675,7 @@
         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,
+    set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
         GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
     break;
   case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
@@ -1689,7 +1684,7 @@
         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,
+    set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
         GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
     break;
   case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
@@ -1769,7 +1764,7 @@
       case GNUNET_TRANSPORT_PS_CONNECT_SENT:
         /* Remove address and request and additional one */
         unset_primary_address (n);
-        set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
+        set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
           GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
         /* Hard failure to send the CONNECT message with this address:
            Destroy address and session */
@@ -1777,7 +1772,7 @@
       case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
         /* Remove address and request and additional one */
         unset_primary_address (n);
-        set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
+        set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
           GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
         break;
       case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
@@ -3284,6 +3279,7 @@
     free_neighbour (n, GNUNET_NO);
     return GNUNET_YES;
   case GNUNET_TRANSPORT_PS_CONNECTED:
+    /* Our primary connection died, try a fast reconnect */
     unset_primary_address (n);
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
         GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -3315,7 +3311,9 @@
     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_ATS, 
GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
+    /* FIXME: Why GNUNET_TRANSPORT_PS_RECONNECT_ATS ?*/
+    set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
+        GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
     break;
   case GNUNET_TRANSPORT_PS_DISCONNECT:
     free_address (&n->primary_address);
@@ -3473,7 +3471,22 @@
   disconnect_neighbour (n);
 }
 
+void delayed_disconnect (void *cls,
+    const struct GNUNET_SCHEDULER_TaskContext* tc)
+{
+  struct NeighbourMapEntry *n = cls;
+  if (GNUNET_YES == test_connected (n))
+    GNUNET_STATISTICS_update (GST_stats,
+                              gettext_noop
+                              ("# other peer asked to disconnect from us"), 1,
+                              GNUNET_NO);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Disconnecting by request from peer %s\n",
+              GNUNET_i2s (&n->id));
+  free_neighbour (n, GNUNET_NO);
+}
 
+
 /**
  * We received a disconnect message from the given peer,
  * validate and process.
@@ -3493,10 +3506,10 @@
               GNUNET_i2s (peer));
   if (ntohs (msg->size) != sizeof (struct SessionDisconnectMessage))
   {
-    // GNUNET_break_op (0);
+    GNUNET_break_op (0);
     GNUNET_STATISTICS_update (GST_stats,
                               gettext_noop
-                              ("# disconnect messages ignored (old format)"), 
1,
+                              ("# disconnect messages ignored (malformed)"), 1,
                               GNUNET_NO);
     return;
   }
@@ -3544,15 +3557,7 @@
     GNUNET_break_op (0);
     return;
   }
-  if (GNUNET_YES == test_connected (n))
-    GNUNET_STATISTICS_update (GST_stats,
-                             gettext_noop
-                             ("# other peer asked to disconnect from us"), 1,
-                             GNUNET_NO);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Disconnecting by request from peer %s\n",
-              GNUNET_i2s (peer));
-  disconnect_neighbour (n);
+  GNUNET_SCHEDULER_add_now (&delayed_disconnect, n);
 }
 
 
@@ -3782,9 +3787,8 @@
     util_transmission_tk = GNUNET_SCHEDULER_NO_TASK;
   }
 
-  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;

Modified: gnunet/src/transport/gnunet-transport.c
===================================================================
--- gnunet/src/transport/gnunet-transport.c     2014-03-27 15:03:17 UTC (rev 
32814)
+++ gnunet/src/transport/gnunet-transport.c     2014-03-27 16:51:32 UTC (rev 
32815)
@@ -124,6 +124,11 @@
 static int try_connect;
 
 /**
+ * Option -D.
+ */
+static int try_disconnect;
+
+/**
  * Option -n.
  */
 static int numeric;
@@ -836,6 +841,25 @@
   if (0 != memcmp (&pid, peer, sizeof(struct GNUNET_PeerIdentity)))
     return;
 
+  if (try_disconnect)
+  {
+    /* all done, terminate instantly */
+    FPRINTF (stdout, _("Successfully disconnected from `%s'\n"),
+        GNUNET_i2s_full (peer));
+    ret = 0;
+
+    if (GNUNET_SCHEDULER_NO_TASK != op_timeout)
+    {
+      GNUNET_SCHEDULER_cancel (op_timeout);
+      op_timeout = GNUNET_SCHEDULER_NO_TASK;
+    }
+
+    if (GNUNET_SCHEDULER_NO_TASK != end)
+      GNUNET_SCHEDULER_cancel (end);
+    end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL );
+    return;
+  }
+
   if (NULL != th)
   {
     GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
@@ -1159,6 +1183,31 @@
   }
 }
 
+static void
+try_disconnect_cb (void *cls, const int result)
+{
+  static int retries = 0;
+  if (GNUNET_OK == result)
+  {
+    tc_handle = NULL;
+    return;
+  }
+  retries++;
+  if (retries < 10)
+    tc_handle = GNUNET_TRANSPORT_try_disconnect (handle, &pid, 
try_disconnect_cb,
+        NULL );
+  else
+  {
+    FPRINTF (stderr, "%s",
+        _("Failed to send connect request to transport service\n") );
+    if (GNUNET_SCHEDULER_NO_TASK != end)
+      GNUNET_SCHEDULER_cancel (end);
+    ret = 1;
+    end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL );
+    return;
+  }
+}
+
 /**
  * Function called with the result of the check if the 'transport'
  * service is running.
@@ -1188,7 +1237,7 @@
   }
 
   counter = benchmark_send + benchmark_receive + iterate_connections
-      + monitor_connections + monitor_connects + try_connect
+      + monitor_connections + monitor_connects + try_connect + try_disconnect +
       + iterate_validation + monitor_validation;
 
   if (1 < counter)
@@ -1238,6 +1287,36 @@
         NULL );
 
   }
+  else if (try_disconnect) /* -D: Disconnect from peer */
+  {
+    if (NULL == cpid)
+    {
+      FPRINTF (stderr, _("Option `%s' makes no sense without option `%s'.\n"),
+          "-D", "-p");
+      ret = 1;
+      return;
+    }
+    handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, &notify_receive,
+        &notify_connect, &notify_disconnect);
+    if (NULL == handle)
+    {
+      FPRINTF (stderr, "%s", _("Failed to connect to transport service\n") );
+      ret = 1;
+      return;
+    }
+    tc_handle = GNUNET_TRANSPORT_try_disconnect (handle, &pid, 
try_disconnect_cb,
+        NULL );
+    if (NULL == tc_handle)
+    {
+      FPRINTF (stderr, "%s",
+          _("Failed to send request to transport service\n") );
+      ret = 1;
+      return;
+    }
+    op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout,
+        NULL );
+
+  }
   else if (benchmark_send) /* -s: Benchmark sending */
   {
     if (NULL == cpid)
@@ -1367,9 +1446,13 @@
               0, &GNUNET_GETOPT_set_one, &iterate_all },
           { 'b', "benchmark", NULL,
               gettext_noop ("measure how fast we are receiving data from all 
peers (until CTRL-C)"),
-              0, &GNUNET_GETOPT_set_one, &benchmark_receive }, { 'C', 
"connect",
+              0, &GNUNET_GETOPT_set_one, &benchmark_receive },
+          { 'C', "connect",
               NULL, gettext_noop ("connect to a peer"), 0,
               &GNUNET_GETOPT_set_one, &try_connect },
+          { 'D', "disconnect",
+              NULL, gettext_noop ("disconnect to a peer"), 0,
+              &GNUNET_GETOPT_set_one, &try_disconnect },
           { 'd', "validation", NULL,
               gettext_noop ("print information for all pending validations "),
               0, &GNUNET_GETOPT_set_one, &iterate_validation },

Modified: gnunet/src/transport/transport.h
===================================================================
--- gnunet/src/transport/transport.h    2014-03-27 15:03:17 UTC (rev 32814)
+++ gnunet/src/transport/transport.h    2014-03-27 16:51:32 UTC (rev 32815)
@@ -176,9 +176,9 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * For alignment.
+   * Connect (GNUNET_YES) or connect (GNUNET_NO).
    */
-  uint32_t reserved;
+  uint32_t connect;
 
   /**
    * Identity of the peer we would like to connect to.

Modified: gnunet/src/transport/transport_api.c
===================================================================
--- gnunet/src/transport/transport_api.c        2014-03-27 15:03:17 UTC (rev 
32814)
+++ gnunet/src/transport/transport_api.c        2014-03-27 16:51:32 UTC (rev 
32815)
@@ -203,6 +203,8 @@
 
   GNUNET_TRANSPORT_TryConnectCallback cb;
 
+  int connect;
+
   /**
    * Closure for @e cb.
    */
@@ -1166,7 +1168,7 @@
   GNUNET_assert (size >= sizeof (struct TransportRequestConnectMessage));
   msg.header.size = htons (sizeof (struct TransportRequestConnectMessage));
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT);
-  msg.reserved = htonl (0);
+  msg.connect = htonl (tch->connect);
   msg.peer = tch->pid;
   memcpy (buf, &msg, sizeof (msg));
   if (NULL != tch->cb)
@@ -1203,6 +1205,7 @@
   tch->pid = *(target);
   tch->cb = cb;
   tch->cb_cls = cb_cls;
+  tch->connect = GNUNET_YES;
   tch->tth = schedule_control_transmit (handle,
                                         sizeof (struct 
TransportRequestConnectMessage),
                                         &send_try_connect, tch);
@@ -1221,6 +1224,7 @@
 GNUNET_TRANSPORT_try_connect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle 
*tch)
 {
   struct GNUNET_TRANSPORT_Handle *th;
+  GNUNET_assert (GNUNET_YES == tch->connect);
 
   th = tch->th;
   cancel_control_transmit (th, tch->tth);
@@ -1228,8 +1232,64 @@
   GNUNET_free (tch);
 }
 
+/**
+ * Ask the transport service to shutdown a connection to
+ * the given peer.
+ *
+ * @param handle connection to transport service
+ * @param target who we should try to connect to
+ * @param cb callback to be called when request was transmitted to transport
+ *         service
+ * @param cb_cls closure for the callback
+ * @return a `struct GNUNET_TRANSPORT_TryConnectHandle` handle or
+ *         NULL on failure (cb will not be called)
+ */
+struct GNUNET_TRANSPORT_TryConnectHandle *
+GNUNET_TRANSPORT_try_disconnect (struct GNUNET_TRANSPORT_Handle *handle,
+                              const struct GNUNET_PeerIdentity *target,
+                              GNUNET_TRANSPORT_TryConnectCallback cb,
+                              void *cb_cls)
+{
+  struct GNUNET_TRANSPORT_TryConnectHandle *tch = NULL;
 
+  if (NULL == handle->client)
+      return NULL;
+  tch = GNUNET_new (struct GNUNET_TRANSPORT_TryConnectHandle);
+  tch->th = handle;
+  tch->pid = *(target);
+  tch->cb = cb;
+  tch->cb_cls = cb_cls;
+  tch->connect = GNUNET_NO;
+  tch->tth = schedule_control_transmit (handle,
+                                        sizeof (struct 
TransportRequestConnectMessage),
+                                        &send_try_connect, tch);
+  GNUNET_CONTAINER_DLL_insert(handle->tc_head, handle->tc_tail, tch);
+  return tch;
+}
+
+
 /**
+ * Cancel the request to transport to try a disconnect
+ * Callback will not be called
+ *
+ * @param tch the handle to cancel
+ */
+void
+GNUNET_TRANSPORT_try_disconnect_cancel (struct 
GNUNET_TRANSPORT_TryConnectHandle *tch)
+{
+  struct GNUNET_TRANSPORT_Handle *th;
+  GNUNET_assert (GNUNET_NO == tch->connect);
+
+  th = tch->th;
+  cancel_control_transmit (th, tch->tth);
+  GNUNET_CONTAINER_DLL_remove (th->tc_head, th->tc_tail, tch);
+  GNUNET_free (tch);
+}
+
+
+
+
+/**
  * Send HELLO message to the service.
  *
  * @param cls the HELLO message to send




reply via email to

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