gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r18103 - gnunet/src/transport
Date: Fri, 11 Nov 2011 11:53:44 +0100

Author: wachs
Date: 2011-11-11 11:53:44 +0100 (Fri, 11 Nov 2011)
New Revision: 18103

Modified:
   gnunet/src/transport/gnunet-service-transport_neighbours.c
Log:
+ moved outbound quota setting to separate function
+ fixed validation error: race condition between address switching and 
disconnect


Modified: gnunet/src/transport/gnunet-service-transport_neighbours.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_neighbours.c  2011-11-10 
22:41:52 UTC (rev 18102)
+++ gnunet/src/transport/gnunet-service-transport_neighbours.c  2011-11-11 
10:53:44 UTC (rev 18103)
@@ -220,6 +220,12 @@
   S_DISCONNECT
 };
 
+enum Address_State
+{
+  USED,
+  UNUSED,
+  FRESH,
+};
 
 /**
  * Entry in neighbours.
@@ -341,6 +347,7 @@
    * Did we sent an KEEP_ALIVE message and are we expecting a response?
    */
   int expect_latency_response;
+  int address_state;
 };
 
 
@@ -519,6 +526,7 @@
     return GNUNET_SYSERR;
   }
 #if DEBUG_TRANSPORT
+
   {
     char *old = GNUNET_strdup (print_state (n->state));
     char *new = GNUNET_strdup (print_state (state));
@@ -844,6 +852,7 @@
   return GNUNET_OK;
 }
 
+
 /**
  * Disconnect from the given neighbour, clean up the record.
  *
@@ -876,15 +885,20 @@
   }
 
   change_state (n, S_DISCONNECT);
-  GST_validation_set_address_use (&n->id,
-                                 n->address,
-                                 n->session,
-                                 GNUNET_NO);
 
-  if (n->state == S_CONNECTED)
+  if (previous_state == S_CONNECTED)
   {
     GNUNET_assert (NULL != n->address);
-    GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
+    if (n->address_state == USED)
+    {
+      GST_validation_set_address_use (&n->id,
+                                      n->address,
+                                      n->session,
+                                      GNUNET_NO);
+
+      GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
+      n->address_state = UNUSED;
+    }
   }
 
   if (n->address != NULL)
@@ -909,7 +923,7 @@
 
   switch (previous_state) {
     case S_CONNECTED:
-      GNUNET_assert (neighbours_connected > 0);
+//      GNUNET_assert (neighbours_connected > 0);
       neighbours_connected--;
       GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task);
       GNUNET_SCHEDULER_cancel (n->keepalive_task);
@@ -1080,7 +1094,7 @@
   GNUNET_CONTAINER_multihashmap_iterate (neighbours, 
&disconnect_all_neighbours,
                                          NULL);
   GNUNET_CONTAINER_multihashmap_destroy (neighbours);
-  GNUNET_assert (neighbours_connected == 0);
+//  GNUNET_assert (neighbours_connected == 0);
   neighbours = NULL;
   callback_cls = NULL;
   connect_notify_cb = NULL;
@@ -1094,6 +1108,21 @@
   struct Session *session;
 };
 
+static void send_outbound_quota (const struct GNUNET_PeerIdentity *target, 
struct GNUNET_BANDWIDTH_Value32NBO quota)
+{
+   struct QuotaSetMessage q_msg;
+#if DEBUG_TRANSPORT
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Sending outbound quota of %u Bps for peer `%s' to all 
clients\n",
+                ntohl (quota.value__), GNUNET_i2s (target));
+#endif
+    q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
+    q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
+    q_msg.quota = quota;
+    q_msg.peer = (*target);
+    GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+}
+
 /**
  * We tried to send a SESSION_CONNECT message to another peer.  If this
  * succeeded, we change the state.  If it failed, we should tell
@@ -1155,7 +1184,6 @@
   GNUNET_free (cc);
 }
 
-
 /**
  * We tried to switch addresses with an peer already connected. If it failed,
  * we should tell ATS to not use this address anymore (until it is 
re-validated).
@@ -1223,29 +1251,23 @@
       GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 
1,
                                 GNUNET_NO);
 
-      GST_validation_set_address_use (&n->id,
-                                      cc->address,
-                                      cc->session,
-                                      GNUNET_YES);
-
+      if (n->address_state == FRESH)
+      {
+          GST_validation_set_address_use (&n->id,
+                    cc->address,
+                    cc->session,
+                    GNUNET_YES);
+          n->address_state = USED;
+      }
       GNUNET_ATS_address_in_use (GST_ats, cc->address, cc->session, 
GNUNET_YES);
 
       if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
             n->keepalive_task = GNUNET_SCHEDULER_add_now 
(&neighbour_keepalive_task, n);
 
       /* Updating quotas */
-      struct QuotaSetMessage q_msg;
       GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
-#if DEBUG_TRANSPORT
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "Sending outbound quota of %u Bps for peer `%s' to all 
clients\n",
-                  ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
-#endif
-      q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
-      q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
-      q_msg.quota = n->bandwidth_out;
-      q_msg.peer = (*target);
-      GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+      send_outbound_quota(target, n->bandwidth_out);
+
     default:
       break;
   }
@@ -1369,7 +1391,7 @@
 
   /* checks successful and neighbour != NULL */
 #if DEBUG_TRANSPORT
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
               "ATS tells us to switch to address '%s' session %p for peer `%s' 
in state `%s'\n",
               GST_plugins_a2s (address),
               session,
@@ -1388,40 +1410,33 @@
                                       n->address)) &&
        (n->session == session) )
   {
-    struct QuotaSetMessage q_msg;
-
     n->bandwidth_in = bandwidth_in;
     n->bandwidth_out = bandwidth_out;
     GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
-    
-#if DEBUG_TRANSPORT
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Sending outbound quota of %u Bps and inbound quota of %u Bps 
for peer `%s' to all clients\n",
-                ntohl (n->bandwidth_out.value__),
-                ntohl (n->bandwidth_in.value__), GNUNET_i2s (peer));
-#endif
-    q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
-    q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
-    q_msg.quota = n->bandwidth_out;
-    q_msg.peer = (*peer);
-    GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+    send_outbound_quota(peer, n->bandwidth_out);
     return GNUNET_NO;    
   }
   if (n->state == S_CONNECTED)
   {
     /* mark old address as no longer used */
     GNUNET_assert (NULL != n->address);
-    GST_validation_set_address_use (&n->id,
-                                   n->address,
-                                   n->session,
-                                   GNUNET_NO);
-    GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
+    if (n->address_state == USED)
+    {
+      GST_validation_set_address_use (&n->id,
+                                      n->address,
+                                      n->session,
+                                      GNUNET_NO);
+      GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
+      n->address_state = UNUSED;
+    }
+
   }
 
   /* set new address */
   if (NULL != n->address)
     GNUNET_HELLO_address_free (n->address);
   n->address = GNUNET_HELLO_address_copy (address);
+  n->address_state = FRESH;
   n->session = session;
   n->bandwidth_in = bandwidth_in;
   n->bandwidth_out = bandwidth_out;
@@ -1472,10 +1487,6 @@
   case S_CONNECTED:
   case S_FAST_RECONNECT:
     /* connected peer is switching addresses or tries fast reconnect*/
-    GST_validation_set_address_use (&n->id,
-                                   n->address,
-                                   n->session,
-                                   GNUNET_YES);
     msg_len = sizeof (struct SessionConnectMessage);
     connect_msg.header.size = htons (msg_len);
     connect_msg.header.type =
@@ -1652,7 +1663,7 @@
   }
 
 #if DEBUG_TRANSPORT
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %X to peer `%s' ended \n",
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Session %X to peer `%s' ended \n",
               session, GNUNET_i2s (peer));
 #endif
 
@@ -1663,11 +1674,15 @@
     return;                     /* doesn't affect us */
   if (n->state == S_CONNECTED)
   {
-    GST_validation_set_address_use (&n->id,
-                                   n->address,
-                                   n->session,
-                                   GNUNET_NO);
-    GNUNET_ATS_address_in_use (GST_ats,n->address, n->session, GNUNET_NO);
+    if (n->address_state == USED)
+    {
+      GST_validation_set_address_use (&n->id,
+                                      n->address,
+                                      n->session,
+                                      GNUNET_NO);
+      GNUNET_ATS_address_in_use (GST_ats,n->address, n->session, GNUNET_NO);
+      n->address_state = UNUSED;
+    }
   }
 
 
@@ -2233,7 +2248,6 @@
                                    uint32_t ats_count)
 {
   const struct SessionConnectMessage *scm;
-  struct QuotaSetMessage q_msg;
   struct GNUNET_MessageHeader msg;
   struct NeighbourMapEntry *n;
   size_t msg_len;
@@ -2284,10 +2298,14 @@
   GNUNET_assert (NULL != n->address);
 
   change_state (n, S_CONNECTED);
-  GST_validation_set_address_use (&n->id,
-                                 n->address,
-                                 n->session,
-                                 GNUNET_YES);
+  if (n->address_state == FRESH)
+  {
+    GST_validation_set_address_use (&n->id,
+            n->address,
+            n->session,
+            GNUNET_YES);
+    n->address_state = USED;
+  }
   GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_YES);
 
   GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
@@ -2324,18 +2342,8 @@
              __LINE__);
 #endif
   connect_notify_cb (callback_cls, &n->id, ats, ats_count);  
+  send_outbound_quota(peer, n->bandwidth_out);
 
-#if DEBUG_TRANSPORT
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sending outbound quota of %u Bps for peer `%s' to all 
clients\n",
-              ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
-#endif
-  q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
-  q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
-  q_msg.quota = n->bandwidth_out;
-  q_msg.peer = (*peer);
-  GST_clients_broadcast (&q_msg.header, GNUNET_NO);
-
 }
 
 
@@ -2348,7 +2356,6 @@
                            uint32_t ats_count)
 {
   struct NeighbourMapEntry *n;
-  struct QuotaSetMessage q_msg;
 
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
@@ -2391,10 +2398,14 @@
 
   if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
         n->keepalive_task = GNUNET_SCHEDULER_add_now 
(&neighbour_keepalive_task, n);
-  GST_validation_set_address_use (&n->id,
+  if (n->address_state == FRESH)
+  {
+    GST_validation_set_address_use (&n->id,
                                  n->address,
                                  n->session,
                                  GNUNET_YES);
+    n->address_state = USED;
+  }
   neighbours_connected++;
   GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
                            GNUNET_NO);
@@ -2407,16 +2418,7 @@
              __LINE__);
 #endif
   connect_notify_cb (callback_cls, &n->id, ats, ats_count);  
-#if DEBUG_TRANSPORT
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sending outbound quota of %u Bps for peer `%s' to all 
clients\n",
-              ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
-#endif
-  q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
-  q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
-  q_msg.quota = n->bandwidth_out;
-  q_msg.peer = (*peer);
-  GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+  send_outbound_quota(peer, n->bandwidth_out);
 }
 
 struct BlackListCheckContext




reply via email to

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