check
[oweals/gnunet.git] / src / core / core_api.c
index a0f72090da8021abe1c0c988e30d4ede4e99c634..195e94e29d0dcf56a8cda2491dbb669b2c9ab4a0 100644 (file)
@@ -82,6 +82,11 @@ struct PeerRecord
    */
   void *pcic_cls;
 
+  /**
+   * Pointer to free when we call pcic.
+   */
+  void *pcic_ptr;
+
   /**
    * Request information ID for the given pcic (needed in case a
    * request is cancelled after being submitted to core and a new
@@ -346,6 +351,11 @@ struct GNUNET_CORE_TransmitHandle
    */
   uint16_t smr_id;
 
+  /**
+   * Is corking allowed?
+   */
+  int cork;
+
 };
 
 
@@ -414,10 +424,14 @@ disconnect_and_free_peer_entry (void *cls,
   if (NULL != (pcic = pr->pcic))
     {
       pr->pcic = NULL;
+      GNUNET_free_non_null (pr->pcic_ptr);
+      pr->pcic_ptr = NULL;
       pcic (pr->pcic_cls,
            &pr->peer,
            zero,
-           0, 0);
+           0, 
+           GNUNET_TIME_UNIT_FOREVER_REL,
+           0);
     }
   if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
     {
@@ -707,6 +721,8 @@ transmit_message (void *cls,
       sm->priority = htonl (th->priority);
       sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
       sm->peer = pr->peer;
+      sm->cork = htonl ((uint32_t) th->cork);
+      sm->reserved = htonl (0);
       ret = th->get_message (th->get_message_cls,
                             size - sizeof (struct SendMessage),
                             &sm[1]);
@@ -720,7 +736,8 @@ transmit_message (void *cls,
 #endif
          /* client decided to send nothing! */
          request_next_transmission (pr);
-         return 0;       
+         GNUNET_free (th);
+         return 0;       
        }
 #if DEBUG_CORE
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -732,7 +749,8 @@ transmit_message (void *cls,
        {
          GNUNET_break (0);
          request_next_transmission (pr);
-         return 0;
+         GNUNET_free (th);
+         return 0;
        }
       ret += sizeof (struct SendMessage);
       sm->header.size = htons (ret);
@@ -987,6 +1005,7 @@ main_notify_handler (void *cls,
       if (NULL == h->status_events)
         {
           GNUNET_break (0);
+         return;
         }
       if (msize < sizeof (struct PeerStatusNotifyMessage))
         {
@@ -1240,11 +1259,14 @@ main_notify_handler (void *cls,
        }
       pcic = pr->pcic;
       pr->pcic = NULL;
+      GNUNET_free_non_null (pr->pcic_ptr);
+      pr->pcic_ptr = NULL;
       if (pcic != NULL)
        pcic (pr->pcic_cls,
              &pr->peer,
              cim->bw_out,
              ntohl (cim->reserved_amount),
+             GNUNET_TIME_relative_ntoh (cim->reserve_delay),
              GNUNET_ntohll (cim->preference));
       break;
     default:
@@ -1532,6 +1554,7 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
   th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
   th->priority = priority;
   th->msize = notify_size;
+  th->cork = cork;
   /* bound queue size */
   if (pr->queue_size == handle->queue_size)
     {
@@ -1547,8 +1570,12 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
       if (minp == NULL) 
        {
          GNUNET_break (handle->queue_size != 0);
-         GNUNET_break (pr->queue_size == 0);
+         GNUNET_break (pr->queue_size == 1);
          GNUNET_free(th);
+#if DEBUG_CORE
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Dropping transmission request: cannot drop queue head and limit is one\n");
+#endif
          return NULL;
        }
       if (priority <= minp->priority)
@@ -1557,6 +1584,7 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                      "Dropping transmission request: priority too low\n");
 #endif
+         GNUNET_free(th);
          return NULL; /* priority too low */
        }
       GNUNET_CONTAINER_DLL_remove (pr->pending_head,
@@ -1737,7 +1765,8 @@ GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
                                           &peer->hashPubKey))
     {
 #if DEBUG_CORE
-      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Peers are already connected!\n");
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 
+                "Peers are already connected!\n");
 #endif
       return NULL;
     }
@@ -1750,9 +1779,9 @@ GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
   msg->reserved = htonl (0);
   msg->timeout = GNUNET_TIME_relative_hton (timeout);
   msg->peer = *peer;
-  GNUNET_CONTAINER_DLL_insert (h->control_pending_head,
-                              h->control_pending_tail,
-                              cm);
+  GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
+                                   h->control_pending_tail,
+                                   cm);
   ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle));
   ret->h = h;
   ret->cm = cm;
@@ -1801,16 +1830,6 @@ struct GNUNET_CORE_InformationRequestContext
    */
   struct GNUNET_CORE_Handle *h;
 
-  /**
-   * Function to call with the information.
-   */
-  GNUNET_CORE_PeerConfigurationInfoCallback info;
-
-  /**
-   * Closure for info.
-   */
-  void *info_cls;
-
   /**
    * Link to control message, NULL if CM was sent.
    */ 
@@ -1895,8 +1914,6 @@ GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
   irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
   irc->h = h;
   irc->pr = pr;
-  irc->info = info;
-  irc->info_cls = info_cls;
   cm = GNUNET_malloc (sizeof (struct ControlMessage) +
                      sizeof (struct RequestInfoMessage));
   cm->cont = &change_preference_send_continuation;
@@ -1914,11 +1931,12 @@ GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Queueing CHANGE PREFERENCE request\n");
 #endif
-  GNUNET_CONTAINER_DLL_insert (h->control_pending_head,
-                              h->control_pending_tail,
-                              cm); 
+  GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
+                                   h->control_pending_tail,
+                                   cm); 
   pr->pcic = info;
   pr->pcic_cls = info_cls;
+  pr->pcic_ptr = irc; /* for free'ing irc */
   if (h->control_pending_head == cm)
     trigger_next_request (h, GNUNET_NO);
   return irc;
@@ -1942,6 +1960,7 @@ GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequest
   struct GNUNET_CORE_Handle *h = irc->h;
   struct PeerRecord *pr = irc->pr;
 
+  GNUNET_assert (pr->pcic_ptr == irc);
   if (irc->cm != NULL)
     {
       GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
@@ -1951,6 +1970,7 @@ GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequest
     }
   pr->pcic = NULL;
   pr->pcic_cls = NULL;
+  pr->pcic_ptr = NULL;
   GNUNET_free (irc);
 }