how did this test ever work without assigning core handles?
[oweals/gnunet.git] / src / core / core_api.c
index c377aedc1b9e1557902915c45ff35ba5bcb7ba1f..959eb275a5d3106b799aea8d8860df250f72ea1f 100644 (file)
@@ -354,7 +354,7 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * @param cls the 'struct GNUNET_CORE_Handle*'
  * @param key the peer identity (not used)
  * @param value the 'struct PeerRecord' to free.
- * @return GNUNET_YES (continue)
+ * @return #GNUNET_YES (continue)
  */
 static int
 disconnect_and_free_peer_entry (void *cls, const struct GNUNET_HashCode * key,
@@ -364,19 +364,19 @@ disconnect_and_free_peer_entry (void *cls, const struct GNUNET_HashCode * key,
   struct GNUNET_CORE_TransmitHandle *th;
   struct PeerRecord *pr = value;
 
-  if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+  if (GNUNET_SCHEDULER_NO_TASK != pr->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (pr->timeout_task);
     pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   }
-  if (pr->ntr_task != GNUNET_SCHEDULER_NO_TASK)
+  if (GNUNET_SCHEDULER_NO_TASK != pr->ntr_task)
   {
     GNUNET_SCHEDULER_cancel (pr->ntr_task);
     pr->ntr_task = GNUNET_SCHEDULER_NO_TASK;
   }
-  if ((pr->prev != NULL) || (pr->next != NULL) || (h->ready_peer_head == pr))
+  if ((NULL != pr->prev) || (NULL != pr->next) || (h->ready_peer_head == pr))
     GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
-  if (h->disconnects != NULL)
+  if (NULL != h->disconnects)
     h->disconnects (h->cls, &pr->peer);
   /* all requests should have been cancelled, clean up anyway, just in case */
   th = &pr->th;
@@ -384,15 +384,15 @@ disconnect_and_free_peer_entry (void *cls, const struct GNUNET_HashCode * key,
   {
     GNUNET_break (0);
     th->peer = NULL;
-    if (th->cm != NULL)
+    if (NULL != th->cm)
       th->cm->th = NULL;
   }
   /* done with 'voluntary' cleanups, now on to normal freeing */
   GNUNET_assert (GNUNET_YES ==
                  GNUNET_CONTAINER_multihashmap_remove (h->peers, key, pr));
   GNUNET_assert (pr->ch == h);
-  GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
-  GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK);
+  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pr->timeout_task);
+  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pr->ntr_task);
   GNUNET_free (pr);
   return GNUNET_YES;
 }
@@ -410,13 +410,13 @@ reconnect_later (struct GNUNET_CORE_Handle *h)
   struct ControlMessage *cm;
   struct PeerRecord *pr;
 
-  GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
+  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task);
   if (NULL != h->cth)
   {
     GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
     h->cth = NULL;
   }
-  if (h->client != NULL)
+  if (NULL != h->client)
   {
     GNUNET_CLIENT_disconnect (h->client);
     h->client = NULL;
@@ -429,9 +429,9 @@ reconnect_later (struct GNUNET_CORE_Handle *h)
   {
     GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
                                  h->control_pending_tail, cm);
-    if (cm->th != NULL)
+    if (NULL != cm->th)
       cm->th->cm = NULL;
-    if (cm->cont != NULL)
+    if (NULL != cm->cont)
       cm->cont (cm->cont_cls, GNUNET_NO);
     GNUNET_free (cm);
   }
@@ -440,9 +440,7 @@ reconnect_later (struct GNUNET_CORE_Handle *h)
   while (NULL != (pr = h->ready_peer_head))
     GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
   GNUNET_assert (h->control_pending_head == NULL);
-  h->retry_backoff =
-      GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS, h->retry_backoff);
-  h->retry_backoff = GNUNET_TIME_relative_multiply (h->retry_backoff, 2);
+  h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
 }
 
 
@@ -537,9 +535,14 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   struct GNUNET_CORE_TransmitHandle *th;
 
   pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  if (GNUNET_SCHEDULER_NO_TASK != pr->ntr_task)
+  {
+    GNUNET_SCHEDULER_cancel (pr->ntr_task);
+    pr->ntr_task = GNUNET_SCHEDULER_NO_TASK;
+  }
   th = &pr->th;
   th->peer = NULL;
-  if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head))
+  if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head))
   {
     /* the request that was 'approved' by core was
      * canceled before it could be transmitted; remove
@@ -566,7 +569,7 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * Transmit the next message to the core service.
  *
  * @param cls closure with the 'struct GNUNET_CORE_Handle'
- * @param size number of bytes available in buf
+ * @param size number of bytes available in @a buf
  * @param buf where the callee should write the message
  * @return number of bytes written to buf 
  */
@@ -584,7 +587,7 @@ transmit_message (void *cls, size_t size, void *buf)
 
   GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
   h->cth = NULL;
-  if (buf == NULL)
+  if (NULL == buf)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Transmission failed, initiating reconnect\n");
@@ -607,7 +610,7 @@ transmit_message (void *cls, size_t size, void *buf)
     memcpy (buf, hdr, msize);
     GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
                                  h->control_pending_tail, cm);
-    if (cm->th != NULL)
+    if (NULL != cm->th)
       cm->th->cm = NULL;
     if (NULL != cm->cont)
       cm->cont (cm->cont_cls, GNUNET_OK);
@@ -627,7 +630,7 @@ transmit_message (void *cls, size_t size, void *buf)
   }
   GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
   th->peer = NULL;
-  if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+  if (GNUNET_SCHEDULER_NO_TASK != pr->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (pr->timeout_task);
     pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
@@ -699,7 +702,7 @@ trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down)
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Request pending, not processing queue\n");
     return;
   }
-  if (h->control_pending_head != NULL)
+  if (NULL != h->control_pending_head)
     msize =
         ntohs (((struct GNUNET_MessageHeader *) &h->
                 control_pending_head[1])->size);
@@ -736,7 +739,6 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
   const struct GNUNET_MessageHeader *em;
   const struct SendMessageReady *smr;
   const struct GNUNET_CORE_MessageHandler *mh;
-  const struct GNUNET_ATS_Information *ats;
   GNUNET_CORE_StartupCallback init;
   struct PeerRecord *pr;
   struct GNUNET_CORE_TransmitHandle *th;
@@ -744,8 +746,6 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
   int trigger;
   uint16_t msize;
   uint16_t et;
-  uint32_t ats_count;
-
   if (NULL == msg)
   {
     LOG (GNUNET_ERROR_TYPE_INFO,
@@ -782,7 +782,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
       h->init = NULL;
       LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to core service of peer `%s'.\n",
            GNUNET_i2s (&h->me));
-      init (h->cls, h, &h->me);
+      init (h->cls, &h->me);
     }
     else
     {
@@ -792,7 +792,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
     /* fake 'connect to self' */
     pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &h->me.hashPubKey);
     GNUNET_assert (NULL == pr);
-    pr = GNUNET_malloc (sizeof (struct PeerRecord));
+    pr = GNUNET_new (struct PeerRecord);
     pr->peer = h->me;
     pr->ch = h;
     GNUNET_assert (GNUNET_YES ==
@@ -800,7 +800,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
                                                       &h->me.hashPubKey, pr,
                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
     if (NULL != h->connects)
-      h->connects (h->cls, &h->me, NULL, 0);
+      h->connects (h->cls, &h->me);
     break;
   case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT:
     if (msize < sizeof (struct ConnectNotifyMessage))
@@ -810,10 +810,8 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
       return;
     }
     cnm = (const struct ConnectNotifyMessage *) msg;
-    ats_count = ntohl (cnm->ats_count);
     if (msize !=
-        sizeof (struct ConnectNotifyMessage) +
-        ats_count * sizeof (struct GNUNET_ATS_Information))
+        sizeof (struct ConnectNotifyMessage))
     {
       GNUNET_break (0);
       reconnect_later (h);
@@ -835,16 +833,15 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
       reconnect_later (h);
       return;
     }
-    pr = GNUNET_malloc (sizeof (struct PeerRecord));
+    pr = GNUNET_new (struct PeerRecord);
     pr->peer = cnm->peer;
     pr->ch = h;
     GNUNET_assert (GNUNET_YES ==
                    GNUNET_CONTAINER_multihashmap_put (h->peers,
                                                       &cnm->peer.hashPubKey, pr,
                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
-    ats = (const struct GNUNET_ATS_Information *) &cnm[1];
     if (NULL != h->connects)
-      h->connects (h->cls, &cnm->peer, ats, ats_count);
+      h->connects (h->cls, &cnm->peer);
     break;
   case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT:
     if (msize != sizeof (struct DisconnectNotifyMessage))
@@ -885,25 +882,21 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
       return;
     }
     ntm = (const struct NotifyTrafficMessage *) msg;
-    ats_count = ntohl (ntm->ats_count);
     if ((msize <
          sizeof (struct NotifyTrafficMessage) +
-         ats_count * sizeof (struct GNUNET_ATS_Information) +
          sizeof (struct GNUNET_MessageHeader)) )
     {
       GNUNET_break (0);
       reconnect_later (h);
       return;
     }
-    ats = (const struct GNUNET_ATS_Information*) &ntm[1];
-    em = (const struct GNUNET_MessageHeader *) &ats[ats_count];
+    em = (const struct GNUNET_MessageHeader *) &ntm[1];
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Received message of type %u and size %u from peer `%4s'\n",
          ntohs (em->type), ntohs (em->size), GNUNET_i2s (&ntm->peer));
     if ((GNUNET_NO == h->inbound_hdr_only) &&
         (msize !=
-         ntohs (em->size) + sizeof (struct NotifyTrafficMessage) +
-         +ats_count * sizeof (struct GNUNET_ATS_Information)))
+         ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
     {
       GNUNET_break (0);
       reconnect_later (h);
@@ -931,15 +924,14 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
        return;
       }
       if (GNUNET_OK !=
-          h->handlers[hpos].callback (h->cls, &ntm->peer, em, ats,
-                                      ats_count))
+          h->handlers[hpos].callback (h->cls, &ntm->peer, em))
       {
         /* error in processing, do not process other messages! */
         break;
       }
     }
     if (NULL != h->inbound_notify)
-      h->inbound_notify (h->cls, &ntm->peer, em, ats, ats_count);
+      h->inbound_notify (h->cls, &ntm->peer, em);
     break;
   case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND:
     if (msize < sizeof (struct NotifyTrafficMessage))
@@ -949,25 +941,21 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
       return;
     }
     ntm = (const struct NotifyTrafficMessage *) msg;
-    ats_count = ntohl (ntm->ats_count);
     if ((msize <
          sizeof (struct NotifyTrafficMessage) +
-         ats_count * sizeof (struct GNUNET_ATS_Information) +
          sizeof (struct GNUNET_MessageHeader)) )
     {
       GNUNET_break (0);
       reconnect_later (h);
       return;
     }
-    ats = (const struct GNUNET_ATS_Information*) &ntm[1];    
-    em = (const struct GNUNET_MessageHeader *) &ats[ats_count];
+    em = (const struct GNUNET_MessageHeader *) &ntm[1];
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Received notification about transmission to `%s'.\n",
          GNUNET_i2s (&ntm->peer));
     if ((GNUNET_NO == h->outbound_hdr_only) &&
         (msize !=
-         ntohs (em->size) + sizeof (struct NotifyTrafficMessage) +
-         ats_count * sizeof (struct GNUNET_ATS_Information)))
+         ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
     {
       GNUNET_break (0);
       reconnect_later (h);
@@ -978,7 +966,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
       GNUNET_break (0);
       break;
     }
-    h->outbound_notify (h->cls, &ntm->peer, em, ats, ats_count);
+    h->outbound_notify (h->cls, &ntm->peer, em);
     break;
   case GNUNET_MESSAGE_TYPE_CORE_SEND_READY:
     if (msize != sizeof (struct SendMessageReady))
@@ -1130,13 +1118,13 @@ reconnect (struct GNUNET_CORE_Handle *h)
  * @param connects function to call on peer connect, can be NULL
  * @param disconnects function to call on peer disconnect / timeout, can be NULL
  * @param inbound_notify function to call for all inbound messages, can be NULL
- * @param inbound_hdr_only set to GNUNET_YES if inbound_notify will only read the
+ * @param inbound_hdr_only set to #GNUNET_YES if inbound_notify will only read the
  *                GNUNET_MessageHeader and hence we do not need to give it the full message;
- *                can be used to improve efficiency, ignored if inbound_notify is NULLL
+ *                can be used to improve efficiency, ignored if @a inbound_notify is NULLL
  * @param outbound_notify function to call for all outbound messages, can be NULL
- * @param outbound_hdr_only set to GNUNET_YES if outbound_notify will only read the
+ * @param outbound_hdr_only set to #GNUNET_YES if outbound_notify will only read the
  *                GNUNET_MessageHeader and hence we do not need to give it the full message
- *                can be used to improve efficiency, ignored if outbound_notify is NULLL
+ *                can be used to improve efficiency, ignored if @a outbound_notify is NULLL
  * @param handlers callbacks for messages we care about, NULL-terminated
  * @return handle to the core service (only useful for disconnect until 'init' is called);
  *                NULL on error (in this case, init is never called)
@@ -1155,7 +1143,8 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
 {
   struct GNUNET_CORE_Handle *h;
 
-  h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle));
+  GNUNET_assert (NULL != cfg);
+  h = GNUNET_new (struct GNUNET_CORE_Handle);
   h->cfg = cfg;
   h->cls = cls;
   h->init = init;
@@ -1168,8 +1157,7 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
   h->handlers = handlers;
   h->hcnt = 0;
   h->currently_down = GNUNET_YES;
-  h->peers = GNUNET_CONTAINER_multihashmap_create (128);
-  h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
+  h->peers = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO);
   if (NULL != handlers)
     while (handlers[h->hcnt].callback != NULL)
       h->hcnt++;
@@ -1194,6 +1182,8 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
 {
   struct ControlMessage *cm;
 
+  GNUNET_assert (NULL != handle);
+
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from CORE service\n");
   if (NULL != handle->cth)
   {
@@ -1233,7 +1223,7 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
 /**
  * Task that calls 'request_next_transmission'.
  *
- * @param cls the 'struct PeerRecord*'
+ * @param cls the 'struct PeerRecord *'
  * @param tc scheduler context
  */
 static void
@@ -1248,13 +1238,13 @@ run_request_next_transmission (void *cls,
 
 
 /**
- * Ask the core to call "notify" once it is ready to transmit the
- * given number of bytes to the specified "target".  Must only be
+ * Ask the core to call @a notify once it is ready to transmit the
+ * given number of bytes to the specified @a target.  Must only be
  * called after a connection to the respective peer has been
  * established (and the client has been informed about this).  You may
  * have one request of this type pending for each connected peer at
  * any time.  If a peer disconnects, the application MUST call
- * "GNUNET_CORE_notify_transmit_ready_cancel" on the respective
+ * #GNUNET_CORE_notify_transmit_ready_cancel on the respective
  * transmission request, if one such request is pending.
  *
  * @param handle connection to core service
@@ -1262,7 +1252,7 @@ run_request_next_transmission (void *cls,
  * @param priority how important is the message?
  * @param maxdelay how long can the message wait?
  * @param target who should receive the message, never NULL (can be this peer's identity for loopback)
- * @param notify_size how many bytes of buffer space does notify want?
+ * @param notify_size how many bytes of buffer space does @a notify want?
  * @param notify function to call when buffer space is available;
  *        will be called with NULL on timeout; clients MUST cancel
  *        all pending transmission requests DURING the disconnect
@@ -1270,7 +1260,7 @@ run_request_next_transmission (void *cls,
  * @param notify_cls closure for notify
  * @return non-NULL if the notify callback was queued,
  *         NULL if we can not even queue the request (request already pending);
- *         if NULL is returned, "notify" will NOT be called.
+ *         if NULL is returned, @a notify will NOT be called.
  */
 struct GNUNET_CORE_TransmitHandle *
 GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork,
@@ -1284,6 +1274,14 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork,
   struct PeerRecord *pr;
   struct GNUNET_CORE_TransmitHandle *th;
 
+  GNUNET_assert (NULL != handle);
+  GNUNET_assert (NULL != target);
+
+  if (notify_size > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
+  {
+     GNUNET_break (0);
+     return NULL;
+  }
   GNUNET_assert (NULL != notify);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Asking core for transmission of %u bytes to `%s'\n",
@@ -1332,6 +1330,7 @@ GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th)
   struct PeerRecord *pr = th->peer;
   struct GNUNET_CORE_Handle *h;
 
+  GNUNET_assert (NULL != th);
   GNUNET_assert (NULL != pr);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Aborting transmission request to core for %u bytes to `%s'\n",
@@ -1362,4 +1361,29 @@ GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th)
 }
 
 
+/**
+ * Check if the given peer is currently connected. This function is for special
+ * cirumstances (GNUNET_TESTBED uses it), normal users of the CORE API are
+ * expected to track which peers are connected based on the connect/disconnect
+ * callbacks from GNUNET_CORE_connect.  This function is NOT part of the
+ * 'versioned', 'official' API. The difference between this function and the
+ * function GNUNET_CORE_is_peer_connected() is that this one returns
+ * synchronously after looking in the CORE API cache. The function
+ * GNUNET_CORE_is_peer_connected() sends a message to the CORE service and hence
+ * its response is given asynchronously.
+ *
+ * @param h the core handle
+ * @param pid the identity of the peer to check if it has been connected to us
+ * @return GNUNET_YES if the peer is connected to us; GNUNET_NO if not
+ */
+int
+GNUNET_CORE_is_peer_connected_sync (const struct GNUNET_CORE_Handle *h,
+                                    const struct GNUNET_PeerIdentity *pid)
+{
+  GNUNET_assert (NULL != h);
+  GNUNET_assert (NULL != pid);
+  return GNUNET_CONTAINER_multihashmap_contains (h->peers, &pid->hashPubKey);
+}
+
+
 /* end of core_api.c */