gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r17770 - gnunet/src/transport
Date: Wed, 26 Oct 2011 11:21:18 +0200

Author: wachs
Date: 2011-10-26 11:21:18 +0200 (Wed, 26 Oct 2011)
New Revision: 17770

Modified:
   gnunet/src/transport/gnunet-service-transport_neighbours_fsm.c
Log:


Modified: gnunet/src/transport/gnunet-service-transport_neighbours_fsm.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_neighbours_fsm.c      
2011-10-26 09:00:53 UTC (rev 17769)
+++ gnunet/src/transport/gnunet-service-transport_neighbours_fsm.c      
2011-10-26 09:21:18 UTC (rev 17770)
@@ -189,7 +189,8 @@
     S_CONNECT_RECV_ACK_SENT = 8,
     /* received ACK or payload */
     S_CONNECTED = 16,
-    S_DISCONNECTED = 32
+    /* Disconnect in progress */
+    S_DISCONNECT = 32
 };
 
 /**
@@ -293,7 +294,7 @@
    * Do we currently consider this neighbour connected? (as far as
    * the connect/disconnect callbacks are concerned)?
    */
-  int is_connected;
+  //int is_connected;
 
   int state;
 
@@ -340,6 +341,30 @@
 #define change_state(n, state, ...) change (n, state, __LINE__)
 
 static int
+is_connecting (struct NeighbourMapEntry * n)
+{
+  if ((n->state > S_NOT_CONNECTED) && (n->state < S_CONNECTED))
+    return GNUNET_YES;
+  return GNUNET_NO;
+}
+
+static int
+is_connected (struct NeighbourMapEntry * n)
+{
+  if (n->state == S_CONNECTED)
+    return GNUNET_YES;
+  return GNUNET_NO;
+}
+
+static int
+is_disconnecting (struct NeighbourMapEntry * n)
+{
+  if (n->state == S_DISCONNECT)
+    return GNUNET_YES;
+  return GNUNET_NO;
+}
+
+static int
 change (struct NeighbourMapEntry * n, int state, int line)
 {
   char * old = NULL;
@@ -358,7 +383,7 @@
     case S_CONNECT_SENT:
       old = "S_CONNECT_SENT";
       break;
-    case S_DISCONNECTED:
+    case S_DISCONNECT:
       old = "S_DISCONNECTED";
       break;
     case S_NOT_CONNECTED:
@@ -382,7 +407,7 @@
     case S_CONNECT_SENT:
       new = "S_CONNECT_SENT";
       break;
-    case S_DISCONNECTED:
+    case S_DISCONNECT:
       new = "S_DISCONNECTED";
       break;
     case S_NOT_CONNECTED:
@@ -424,7 +449,7 @@
       break;
     }
     break;
-  case S_DISCONNECTED:
+  case S_DISCONNECT:
     break;
   default:
     GNUNET_break (0);
@@ -447,6 +472,49 @@
   return GNUNET_OK;
 }
 
+static ssize_t
+send_with_plugin (void *cls,
+    const struct GNUNET_PeerIdentity * target,
+    const char *msgbuf,
+    size_t msgbuf_size,
+    uint32_t priority,
+    struct GNUNET_TIME_Relative timeout,
+    struct Session * session,
+    const char * plugin_name,
+    const void *addr,
+    size_t addrlen,
+    int force_address,
+    GNUNET_TRANSPORT_TransmitContinuation cont,
+    void *cont_cls)
+
+{
+  struct GNUNET_TRANSPORT_PluginFunctions *papi;
+  size_t ret = GNUNET_SYSERR;
+
+  papi = GST_plugins_find (plugin_name);
+  GNUNET_assert (papi != NULL);
+
+  ret = papi->send (papi->cls,
+      target,
+      msgbuf, msgbuf_size,
+      0,
+      timeout,
+      session,
+      addr, addrlen,
+      GNUNET_YES,
+      cont, cont_cls);
+
+  if (ret == -1)
+  {
+    cont (cont_cls, target, GNUNET_SYSERR);
+  }
+  else
+  {
+    cont (cont_cls, target, GNUNET_OK);
+  }
+  return ret;
+}
+
 /**
  * Task invoked to start a transmission to another peer.
  *
@@ -612,6 +680,15 @@
 {
   struct MessageQueue *mq;
 
+  if (is_disconnecting(n) == GNUNET_YES)
+    return;
+
+  /* send DISCONNECT MESSAGE */
+  if (is_connected(n) || is_connecting(n))
+  {
+    change_state (n, S_DISCONNECT);
+  }
+
   if (GNUNET_YES == n->in_disconnect)
     return;
   n->in_disconnect = GNUNET_YES;
@@ -627,7 +704,7 @@
     n->is_active->n = NULL;
     n->is_active = NULL;
   }
-  if (n->state == S_CONNECTED)
+  if (is_connected (n))
   {
     change_state (n, S_NOT_CONNECTED);
     GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task);
@@ -683,8 +760,8 @@
   struct NeighbourMapEntry *n = cls;
 
   n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
-  if (GNUNET_YES == n->is_connected)
-    GNUNET_STATISTICS_update (GST_stats,
+
+  GNUNET_STATISTICS_update (GST_stats,
                             gettext_noop ("# peers disconnected due to 
timeout"), 1,
                             GNUNET_NO);
   disconnect_neighbour (n);
@@ -703,25 +780,23 @@
 {
   struct NeighbourMapEntry *n = cls;
   struct GNUNET_MessageHeader m;
-  struct GNUNET_TRANSPORT_PluginFunctions *papi;
 
   n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
                                                    &neighbour_keepalive_task,
                                                    n);
-  GNUNET_assert (GNUNET_YES == n->is_connected);
+  GNUNET_assert (is_connected(n));
   GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop ("# keepalives sent"), 1,
                            GNUNET_NO);
   m.size = htons (sizeof (struct GNUNET_MessageHeader));
   m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE);
-  papi = GST_plugins_find (n->plugin_name);
-  if (papi != NULL)
-    papi->send (papi->cls, 
-               &n->id, (const void *) &m,
-               sizeof (m),
-               UINT32_MAX /* priority */ ,
-               GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->addr, n->addrlen,
-               GNUNET_YES, NULL, NULL);
+
+  send_with_plugin(NULL, &n->id, (const void *) &m,
+                   sizeof (m),
+                   UINT32_MAX /* priority */ ,
+                   GNUNET_TIME_UNIT_FOREVER_REL,
+                   n->session, n->plugin_name, n->addr, n->addrlen,
+                   GNUNET_YES, NULL, NULL);
 }
 
 
@@ -741,7 +816,7 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s', %s\n",
               GNUNET_i2s (&n->id), "SHUTDOWN_TASK");
 #endif
-  if (GNUNET_YES == n->is_connected)
+  if (n->state == S_CONNECTED)
     GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop ("# peers disconnected due to global 
disconnect"), 1,
                              GNUNET_NO);
@@ -771,7 +846,7 @@
 
 /**
  * We tried to send a SESSION_CONNECT message to another peer.  If this
- * succeeded, we should mark the peer up.  If it failed, we should tell
+ * succeeded, we change the state.  If it failed, we should tell
  * ATS to not use this address anymore (until it is re-validated).
  *
  * @param cls the 'struct NeighbourMapEntry'
@@ -779,7 +854,9 @@
  */
 static void
 send_connect_continuation (void *cls,
-                          int success)
+      const struct GNUNET_PeerIdentity * target,
+      int success)
+
 {
   struct NeighbourMapEntry *n = cls;
 
@@ -788,14 +865,25 @@
     return; /* neighbour is going away */
   if (GNUNET_YES != success)
   {
+#if DEBUG_TRANSPORT
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Failed to send CONNECT_MSG to peer `%4s' with plugin `%s' 
address '%s' session %X, asking ATS for new address \n",
+              GNUNET_i2s (&n->id), n->plugin_name,
+              (n->addrlen == 0) ? "<inbound>" : GST_plugins_a2s 
(n->plugin_name,
+                                                                  n->addr,
+                                                                  n->addrlen),
+              n->session);
+#endif
     change_state(n, S_NOT_CONNECTED);
+
     GNUNET_ATS_address_destroyed (GST_ats,
                                  &n->id,
                                  n->plugin_name, 
                                  n->addr,
                                  n->addrlen,
                                  NULL);
-    disconnect_neighbour (n);
+
+    GNUNET_ATS_suggest_address(GST_ats, &n->id);
     return;
   }
 }
@@ -825,7 +913,8 @@
 {
   struct NeighbourMapEntry *n;
   struct SessionConnectMessage connect_msg;
-  //int was_connected;
+  size_t len;
+  size_t ret;
 
   GNUNET_assert (neighbours != NULL);
   n = lookup_neighbour (peer);
@@ -838,13 +927,6 @@
                                    address_len, NULL);    
     return GNUNET_NO;
   }
-  /*
-  was_connected = n->is_connected;
-  n->is_connected = GNUNET_YES;
-  if (GNUNET_YES != was_connected)
-    n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
-                                                     &neighbour_keepalive_task,
-                                                     n);*/
 
   change_state (n, S_CONNECT_SENT);
 
@@ -868,26 +950,26 @@
   n->timeout_task =
       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                     &neighbour_timeout_task, n);
-  connect_msg.header.size = htons (sizeof (struct SessionConnectMessage));
+
+  len = sizeof (struct SessionConnectMessage);
+  connect_msg.header.size = htons (len);
   connect_msg.header.type =
       htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT);
   connect_msg.reserved = htonl (0);
   connect_msg.timestamp =
       GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
-  GST_neighbours_send (peer, &connect_msg, sizeof (connect_msg),
-                       GNUNET_TIME_UNIT_FOREVER_REL, 
-                      &send_connect_continuation, 
-                      n);
-  /*
-  if (GNUNET_YES == was_connected)
-    return GNUNET_YES;
-  // First tell clients about connected neighbours...
-  neighbours_connected++;
-  GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
-                            GNUNET_NO);
-  connect_notify_cb (callback_cls, peer, ats, ats_count);
-  return GNUNET_YES;*/
-  /* connection not yet up */
+
+  ret =send_with_plugin (NULL, peer, (const char *) &connect_msg, len, 0, 
GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, 
GNUNET_YES, &send_connect_continuation, n);
+  if (ret == GNUNET_SYSERR)
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Failed to send CONNECT_MESSAGE to `%4s' using plugin `%s' 
address '%s' session %X\n",
+              GNUNET_i2s (peer), plugin_name,
+              (address_len == 0) ? "<inbound>" : GST_plugins_a2s (plugin_name,
+                                                                  address,
+                                                                  address_len),
+              session);
+
+
   return GNUNET_NO;
 }
 
@@ -946,7 +1028,7 @@
                  memcmp (target, &GST_my_identity,
                          sizeof (struct GNUNET_PeerIdentity)));
   n = lookup_neighbour (target);
-  if ((NULL != n) && (GNUNET_YES == n->is_connected))
+  if ((NULL != n) && (n->state > S_CONNECTED))
     return;                     /* already connected */
 
   if ((NULL != n) && (n->state > S_NOT_CONNECTED))
@@ -1015,7 +1097,7 @@
   n->addrlen = 0;
 
 
-  if (GNUNET_YES != n->is_connected)
+  if (!is_connected(n))
     return;                     /* not connected anymore anyway, shouldn't 
matter */
   /* fast disconnect unless ATS suggests a new address */
   GNUNET_SCHEDULER_cancel (n->timeout_task);
@@ -1048,8 +1130,7 @@
   GNUNET_assert (neighbours != NULL);
 
   n = lookup_neighbour (target);
-  /* FIXME */
-  if ((n == NULL) /* || (GNUNET_YES != n->is_connected)*/)
+  if ((n == NULL) || (n->state != S_CONNECTED))
   {
     GNUNET_STATISTICS_update (GST_stats,
                               gettext_noop
@@ -1060,7 +1141,7 @@
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Could not send message to peer `%s': unknown neighbor",
                   GNUNET_i2s (target));
-    else if (GNUNET_YES != n->is_connected)
+    else if (n->state != S_CONNECTED)
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Could not send message to peer `%s': not connected\n",
                   GNUNET_i2s (target));
@@ -1069,7 +1150,7 @@
       cont (cont_cls, GNUNET_SYSERR);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u\n", __LINE__);
+
   if ((n->session == NULL) && (n->addr == NULL) && (n->addrlen ==0))
   {
     GNUNET_STATISTICS_update (GST_stats,
@@ -1086,7 +1167,6 @@
       cont (cont_cls, GNUNET_SYSERR);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u\n", __LINE__);
   GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader));
   GNUNET_STATISTICS_update (GST_stats,
                             gettext_noop
@@ -1146,7 +1226,7 @@
       return GNUNET_TIME_UNIT_ZERO;
     }
   }
-  if (GNUNET_YES != n->is_connected)
+  if (!is_connected(n))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Plugin gave us %d bytes of data but somehow the session is 
not marked as UP yet!\n"),
@@ -1263,7 +1343,7 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s' due to 
`%s'\n",
               GNUNET_i2s (&n->id), "SET_QUOTA");
 #endif
-  if (GNUNET_YES == n->is_connected)
+  if (is_connected(n))
     GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop ("# disconnects due to quota of 0"), 
1,
                              GNUNET_NO);
@@ -1302,7 +1382,7 @@
   struct IteratorContext *ic = cls;
   struct NeighbourMapEntry *n = value;
 
-  if (GNUNET_YES != n->is_connected)
+  if (is_connected(n))
     return GNUNET_OK;
 
   ic->cb (ic->cb_cls, &n->id, NULL, 0, n->plugin_name, n->addr, n->addrlen);
@@ -1328,7 +1408,39 @@
   GNUNET_CONTAINER_multihashmap_iterate (neighbours, &neighbours_iterate, &ic);
 }
 
+static void
+send_disconnect (struct NeighbourMapEntry *n)
+{
+  size_t ret;
+  struct SessionDisconnectMessage disconnect_msg;
 
+  disconnect_msg.header.size = htons (sizeof (struct 
SessionDisconnectMessage));
+  disconnect_msg.header.type = htons 
(GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
+  disconnect_msg.reserved = htonl (0);
+  disconnect_msg.purpose.size = htonl (sizeof (struct 
GNUNET_CRYPTO_RsaSignaturePurpose) +
+                                       sizeof (struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
+                                       sizeof (struct GNUNET_TIME_AbsoluteNBO) 
);
+  disconnect_msg.purpose.purpose = htonl 
(GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT);
+  disconnect_msg.timestamp = GNUNET_TIME_absolute_hton 
(GNUNET_TIME_absolute_get ());
+  disconnect_msg.public_key = GST_my_public_key;
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CRYPTO_rsa_sign (GST_my_private_key,
+                                         &disconnect_msg.purpose,
+                                         &disconnect_msg.signature));
+
+  ret = send_with_plugin(NULL, &n->id,
+      (const char *) &disconnect_msg, sizeof (disconnect_msg),
+      UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, 
n->addr, n->addrlen,
+      GNUNET_YES, NULL, NULL);
+
+  GNUNET_STATISTICS_update (GST_stats,
+                            gettext_noop ("# peers disconnected due to 
external request"), 1,
+                            GNUNET_NO);
+
+  if (n->state != S_DISCONNECT)
+    change_state (n, S_DISCONNECT);
+}
+
 /**
  * If we have an active connection to the given target, it must be shutdown.
  *
@@ -1338,9 +1450,6 @@
 GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target)
 {
   struct NeighbourMapEntry *n;
-  struct GNUNET_TRANSPORT_PluginFunctions *papi;
-  struct SessionDisconnectMessage disconnect_msg;
-  int ret;
 
   GNUNET_assert (neighbours != NULL);
 
@@ -1349,37 +1458,8 @@
     return;                     /* not active */
   if (n->state == S_CONNECTED)
   {
-    /* we're actually connected, send DISCONNECT message */
-    disconnect_msg.header.size = htons (sizeof (struct 
SessionDisconnectMessage));
-    disconnect_msg.header.type = htons 
(GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
-    disconnect_msg.reserved = htonl (0);
-    disconnect_msg.purpose.size = htonl (sizeof (struct 
GNUNET_CRYPTO_RsaSignaturePurpose) +
-                                        sizeof (struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
-                                        sizeof (struct 
GNUNET_TIME_AbsoluteNBO) );
-    disconnect_msg.purpose.purpose = htonl 
(GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT);
-    disconnect_msg.timestamp = GNUNET_TIME_absolute_hton 
(GNUNET_TIME_absolute_get ());
-    disconnect_msg.public_key = GST_my_public_key;
-    GNUNET_assert (GNUNET_OK ==
-                  GNUNET_CRYPTO_rsa_sign (GST_my_private_key,
-                                          &disconnect_msg.purpose,
-                                          &disconnect_msg.signature));
+    send_disconnect(n);
 
-    papi = GST_plugins_find (n->plugin_name);
-    if (papi != NULL)
-    {
-      ret = papi->send (papi->cls, target, (const void *) &disconnect_msg,
-                  sizeof (disconnect_msg),
-                  UINT32_MAX /* priority */ ,
-                  GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->addr, 
n->addrlen,
-                  GNUNET_YES, NULL, NULL);
-      GNUNET_STATISTICS_update (GST_stats,
-                             gettext_noop ("# peers disconnected due to 
external request"), 1,
-                             GNUNET_NO);
-      if (ret == GNUNET_SYSERR)
-        change_state (n, S_NOT_CONNECTED);
-      else
-        change_state (n, S_DISCONNECTED);
-    }
     n = lookup_neighbour (target);
     if (NULL == n)
       return;                     /* gone already */
@@ -1457,12 +1537,13 @@
               const struct GNUNET_ATS_Information *ats,
               uint32_t ats_count)
 {
-  struct GNUNET_TRANSPORT_PluginFunctions *papi;
-  struct SessionConnectMessage scm;
+  struct GNUNET_MessageHeader msg;
+  size_t msg_len;
   int ret;
 
   if (n->state == S_CONNECTED)
     return;
+
   change_state (n, S_CONNECTED);
 
   n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
@@ -1470,20 +1551,20 @@
                                                       n);
 
   /* send CONNECT_ACK (SYN_ACK)*/
-  scm.header.size = htons (sizeof (struct SessionConnectMessage));
-  scm.header.type =
-      htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK);
-  scm.reserved = htonl (0);
-  scm.timestamp =
-      GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
+  msg_len =  sizeof (msg);
+  msg.size = htons (msg_len);
+  msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK);
 
-  papi = GST_plugins_find (n->plugin_name);
-  ret = papi->send (papi->cls, &n->id, (const char *) &scm, sizeof (struct 
SessionConnectMessage),
-                  0,
-                  GNUNET_TIME_UNIT_FOREVER_REL, NULL, n->addr, n->addrlen, 
GNUNET_YES,
-                  NULL, NULL);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-      "neighbour_connected %i\n", ret);
+  ret = send_with_plugin (NULL, &n->id, (const char *) &msg, msg_len, 0,
+      GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, n->addr, 
n->addrlen, GNUNET_YES, NULL, NULL);
+  if (ret == GNUNET_SYSERR)
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Failed to send CONNECT_MESSAGE to `%4s' using plugin `%s' 
address '%s' session %X\n",
+              GNUNET_i2s (&n->id), n->plugin_name,
+              (n->addrlen == 0) ? "<inbound>" : GST_plugins_a2s 
(n->plugin_name,
+                                                                 n->addr,
+                                                                 n->addrlen),
+              n->session);
 
   neighbours_connected++;
   GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,




reply via email to

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