misc minor fixes
[oweals/gnunet.git] / src / core / gnunet-service-core_sessions.c
index e4702a03a0327dff77b88f8bd611e2ea8ac498f7..0a547be1b24ad5a201b0516964c8256de79f64ee 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009-2014 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2009-2014 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
@@ -125,12 +125,12 @@ struct Session
   /**
    * Task to transmit corked messages with a delay.
    */
-  struct GNUNET_SCHEDULER_Task * cork_task;
+  struct GNUNET_SCHEDULER_Task *cork_task;
 
   /**
    * Task to transmit our type map.
    */
-  struct GNUNET_SCHEDULER_Task * typemap_task;
+  struct GNUNET_SCHEDULER_Task *typemap_task;
 
   /**
    * Retransmission delay we currently use for the typemap
@@ -229,7 +229,8 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
   {
     GNUNET_CONTAINER_DLL_remove (session->active_client_request_head,
                                  session->active_client_request_tail, car);
-    GSC_CLIENTS_reject_request (car);
+    GSC_CLIENTS_reject_request (car,
+                                GNUNET_NO);
   }
   while (NULL != (sme = session->sme_head))
   {
@@ -263,11 +264,9 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
  * (Done periodically until the typemap is confirmed).
  *
  * @param cls the `struct Session *`
- * @param tc unused
  */
 static void
-transmit_typemap_task (void *cls,
-                       const struct GNUNET_SCHEDULER_TaskContext *tc)
+transmit_typemap_task (void *cls)
 {
   struct Session *session = cls;
   struct GNUNET_MessageHeader *hdr;
@@ -486,19 +485,22 @@ GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car)
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Dropped client request for transmission (am disconnected)\n");
     GNUNET_break (0);           /* should have been rejected earlier */
-    GSC_CLIENTS_reject_request (car);
+    GSC_CLIENTS_reject_request (car,
+                                GNUNET_NO);
     return;
   }
   if (car->msize > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
   {
     GNUNET_break (0);
-    GSC_CLIENTS_reject_request (car);
+    GSC_CLIENTS_reject_request (car,
+                                GNUNET_YES);
     return;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received client transmission request. queueing\n");
   GNUNET_CONTAINER_DLL_insert (session->active_client_request_head,
-                               session->active_client_request_tail, car);
+                               session->active_client_request_tail,
+                               car);
   try_transmission (session);
 }
 
@@ -515,7 +517,8 @@ GSC_SESSIONS_dequeue_request (struct GSC_ClientActiveRequest *car)
   struct Session *session;
 
   if (0 ==
-      memcmp (&car->target, &GSC_my_identity,
+      memcmp (&car->target,
+              &GSC_my_identity,
               sizeof (struct GNUNET_PeerIdentity)))
     return;
   session = find_session (&car->target);
@@ -523,41 +526,10 @@ GSC_SESSIONS_dequeue_request (struct GSC_ClientActiveRequest *car)
   GNUNET_CONTAINER_DLL_remove (session->active_client_request_head,
                                session->active_client_request_tail,
                                car);
-}
-
-
-/**
- * Discard all expired active transmission requests from clients.
- *
- * @param session session to clean up
- */
-static void
-discard_expired_requests (struct Session *session)
-{
-  struct GSC_ClientActiveRequest *pos;
-  struct GSC_ClientActiveRequest *nxt;
-  struct GNUNET_TIME_Absolute now;
-
-  now = GNUNET_TIME_absolute_get ();
-  pos = NULL;
-  nxt = session->active_client_request_head;
-  while (NULL != nxt)
-  {
-    pos = nxt;
-    nxt = pos->next;
-    if ( (pos->deadline.abs_value_us < now.abs_value_us) &&
-         (GNUNET_YES != pos->was_solicited) )
-    {
-      GNUNET_STATISTICS_update (GSC_stats,
-                                gettext_noop
-                                ("# messages discarded (expired prior to transmission)"),
-                                1, GNUNET_NO);
-      GNUNET_CONTAINER_DLL_remove (session->active_client_request_head,
-                                   session->active_client_request_tail,
-                                   pos);
-      GSC_CLIENTS_reject_request (pos);
-    }
-  }
+  /* dequeueing of 'high' priority messages may unblock
+     transmission for lower-priority messages, so we also
+     need to try in this case. */
+  try_transmission (session);
 }
 
 
@@ -577,7 +549,6 @@ solicit_messages (struct Session *session,
   size_t so_size;
   enum GNUNET_CORE_Priority pmax;
 
-  discard_expired_requests (session);
   so_size = msize;
   pmax = GNUNET_CORE_PRIO_BACKGROUND;
   for (car = session->active_client_request_head; NULL != car; car = car->next)
@@ -598,7 +569,15 @@ solicit_messages (struct Session *session,
     if (GNUNET_YES == car->was_solicited)
       continue;
     car->was_solicited = GNUNET_YES;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Soliciting message with priority %u\n",
+                car->priority);
     GSC_CLIENTS_solicit_request (car);
+    /* The above call may *dequeue* requests and thereby
+       clobber 'nxt'. Hence we need to restart from the
+       head of the list. */
+    nxt = session->active_client_request_head;
+    so_size = msize;
   }
 }
 
@@ -608,11 +587,9 @@ solicit_messages (struct Session *session,
  * Send them now.
  *
  * @param cls `struct Session` with the messages to transmit now
- * @param tc scheduler context (unused)
  */
 static void
-pop_cork_task (void *cls,
-               const struct GNUNET_SCHEDULER_TaskContext *tc)
+pop_cork_task (void *cls)
 {
   struct Session *session = cls;
 
@@ -641,14 +618,22 @@ try_transmission (struct Session *session)
   int excess;
 
   if (GNUNET_YES != session->ready_to_transmit)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Already ready to transmit, not evaluating queue\n");
     return;
+  }
   msize = 0;
   min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
   /* if the peer has excess bandwidth, background traffic is allowed,
      otherwise not */
-  if (MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE >=
-      GSC_NEIGHBOURS_check_excess_bandwidth (&session->peer))
+  if (MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE <=
+      GSC_NEIGHBOURS_get_queue_size (&session->peer))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Transmission queue already very long, waiting...\n");
     return; /* queue already too long */
+  }
   excess = GSC_NEIGHBOURS_check_excess_bandwidth (&session->peer);
   if (GNUNET_YES == excess)
     maxp = GNUNET_CORE_PRIO_BACKGROUND;
@@ -685,7 +670,8 @@ try_transmission (struct Session *session)
     {
       if (GNUNET_YES == car->was_solicited)
         continue;
-      maxpc = GNUNET_MAX (maxpc, car->priority);
+      maxpc = GNUNET_MAX (maxpc,
+                          car->priority);
     }
     if (maxpc > maxp)
     {
@@ -720,7 +706,7 @@ try_transmission (struct Session *session)
                 "Soliciting messages (excess %d, maxpc %d, message size %u, deadline %s)\n",
                 excess,
                 maxpc,
-                msize,
+                (unsigned int) msize,
                 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (min_deadline),
                                                         GNUNET_YES));
     solicit_messages (session,
@@ -740,6 +726,11 @@ try_transmission (struct Session *session)
                                         &pop_cork_task,
                                         session);
     }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Queue empty, waiting for solicitations\n");
+    }
     return;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,