gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r10667 - gnunet/src/transport
Date: Fri, 19 Mar 2010 14:42:36 +0100

Author: grothoff
Date: 2010-03-19 14:42:36 +0100 (Fri, 19 Mar 2010)
New Revision: 10667

Modified:
   gnunet/src/transport/gnunet-service-transport.c
   gnunet/src/transport/plugin_transport_tcp.c
Log:
better session selection


Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c     2010-03-19 13:22:43 UTC 
(rev 10666)
+++ gnunet/src/transport/gnunet-service-transport.c     2010-03-19 13:42:36 UTC 
(rev 10667)
@@ -866,11 +866,6 @@
 
 /**
  * Find an entry in the neighbour list for a particular peer.
- * if sender_address is not specified (NULL) then return the
- * first matching entry.  If sender_address is specified, then
- * make sure that the address and address_len also matches.
- * 
- * FIXME: This description does not fit the function.
  *  
  * @return NULL if not found.
  */
@@ -1241,6 +1236,7 @@
   struct MessageQueue *mq;
   struct GNUNET_TIME_Relative timeout;
   ssize_t ret;
+  int force_address;
 
   if (neighbour->messages_head == NULL)
     {
@@ -1252,6 +1248,7 @@
   rl = NULL;
   mq = neighbour->messages_head;
   /* FIXME: support bi-directional use of TCP */
+  force_address = GNUNET_YES;
   if (mq->specific_address == NULL)
     {
       mq->specific_address = find_ready_address(neighbour); 
@@ -1259,6 +1256,7 @@
                                gettext_noop ("# transport selected peer 
address freely"),
                                1,
                                GNUNET_NO); 
+      force_address = GNUNET_NO;
     }
   if (mq->specific_address == NULL)
     {
@@ -1347,7 +1345,7 @@
                               GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                               mq->specific_address->addr,
                               mq->specific_address->addrlen,
-                              GNUNET_YES /* FIXME: sometimes, we want to be 
more tolerant here! */,
+                              force_address,
                               &transmit_send_continuation, mq);
   if (ret == -1)
     {

Modified: gnunet/src/transport/plugin_transport_tcp.c
===================================================================
--- gnunet/src/transport/plugin_transport_tcp.c 2010-03-19 13:22:43 UTC (rev 
10666)
+++ gnunet/src/transport/plugin_transport_tcp.c 2010-03-19 13:42:36 UTC (rev 
10667)
@@ -174,6 +174,12 @@
   void *connect_addr;
 
   /**
+   * Last activity on this connection.  Used to select preferred
+   * connection.
+   */
+  struct GNUNET_TIME_Absolute last_activity;
+
+  /**
    * Length of connect_addr.
    */
   size_t connect_alen;
@@ -297,6 +303,7 @@
                   "Creating new session for peer `%4s'\n",
                   GNUNET_i2s (target));
   ret = GNUNET_malloc (sizeof (struct Session));
+  ret->last_activity = GNUNET_TIME_absolute_get ();
   ret->plugin = plugin;
   ret->next = plugin->sessions;
   plugin->sessions = ret;
@@ -438,6 +445,7 @@
      cancel everything don't cause us to use a session that no longer
      exists... */
   process_pending_messages (session);  
+  session->last_activity = GNUNET_TIME_absolute_get ();
   pid = session->target;
   /* we'll now call callbacks that may cancel the session; hence
      we should not use 'session' after this point */
@@ -580,6 +588,41 @@
 
 
 /**
+ * Given two otherwise equivalent sessions, pick the better one.
+ * 
+ * @param s1 one session (also default)
+ * @param s2 other session
+ * @return "better" session (more active)
+ */
+static struct Session *
+select_better_session (struct Session *s1,
+                      struct Session *s2)
+{
+  if (s1 == NULL)
+    return s2;
+  if (s2 == NULL)
+    return s1;
+  if ( (s1->expecting_welcome == GNUNET_NO) &&
+       (s2->expecting_welcome == GNUNET_YES) )
+    return s1;
+  if ( (s1->expecting_welcome == GNUNET_YES) &&
+       (s2->expecting_welcome == GNUNET_NO) )
+    return s2;
+  if (s1->last_activity.value < s2->last_activity.value)
+    return s2;
+  if (s1->last_activity.value > s2->last_activity.value)
+    return s1;
+  if ( (GNUNET_YES == s1->inbound) &&
+       (GNUNET_NO  == s2->inbound) )
+    return s1;
+  if ( (GNUNET_NO  == s1->inbound) &&
+       (GNUNET_YES == s2->inbound) )
+    return s2;
+  return s1;
+}
+
+
+/**
  * Function that can be used by the transport service to transmit
  * a message using the plugin.   Note that in the case of a
  * peer disconnecting, the continuation MUST be called
@@ -628,6 +671,7 @@
 {
   struct Plugin *plugin = cls;
   struct Session *session;
+  struct Session *cand_session;
   struct Session *next;
   struct PendingMessage *pm;
   struct GNUNET_CONNECTION_Handle *sa;
@@ -640,25 +684,24 @@
   /* FIXME: we could do this a cheaper with a hash table
      where we could restrict the iteration to entries that match
      the target peer... */
+  cand_session = NULL;
   next = plugin->sessions;
   while (NULL != (session = next)) 
     {
       next = session->next;
-      if (session->client == NULL) 
-       continue;
+      GNUNET_assert (session->client != NULL);
       if (0 != memcmp (target,
                       &session->target, 
                       sizeof (struct GNUNET_PeerIdentity)))
        continue;
-      if (GNUNET_SYSERR == force_address) 
+      if ( ( (GNUNET_SYSERR == force_address) &&
+            (session->expecting_welcome == GNUNET_NO) ) ||
+          (GNUNET_NO == force_address) )   
        {
-         if (session->expecting_welcome == GNUNET_NO)
-           break; /* established and reliable (TCP!) */
-         else
-           continue; /* not established */
+         cand_session = select_better_session (cand_session,
+                                               session);
+         continue;
        }
-      if (GNUNET_NO == force_address)
-       break;
       GNUNET_break (GNUNET_YES == force_address);
       if (addr == NULL)
        {
@@ -669,11 +712,14 @@
        continue;
       if (addrlen != session->connect_alen)
        continue;
-      if (0 == memcmp (session->connect_addr,
+      if (0 != memcmp (session->connect_addr,
                       addr,
                       addrlen))
-       break;
+       continue;
+      cand_session = select_better_session (cand_session,
+                                           session);         
     }
+  session = cand_session;
   if ( (session == NULL) &&
        (addr == NULL) )
     {
@@ -1112,18 +1158,19 @@
   struct Session *session;
   struct GNUNET_TIME_Relative delay;
 
-  session = find_session_by_client (plugin, client);
   if (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == ntohs(message->type))
     {
       /* We don't want to propagate WELCOME messages up! */
       GNUNET_SERVER_receive_done (client, GNUNET_OK);
       return; 
     }    
+  session = find_session_by_client (plugin, client);
   if ( (NULL == session) || (GNUNET_NO != session->expecting_welcome))
     {
       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
       return;
     }
+  session->last_activity = GNUNET_TIME_absolute_get ();
 #if DEBUG_TCP
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
                    "tcp", 





reply via email to

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