fix for coverity
[oweals/gnunet.git] / src / fs / gnunet-service-fs_mesh_client.c
index 73ab6bb5d7c821e49b21dc791cd798b1fe2af358..95e3702741527b2215cc97efd31c4026a861a096 100644 (file)
@@ -92,8 +92,8 @@ struct GSF_MeshRequest
   enum GNUNET_BLOCK_Type type;
 
   /**
-   * Did we transmit this request already? YES if we are
-   * in the 'waiting_map', NO if we are in the 'pending' DLL.
+   * Did we transmit this request already? #GNUNET_YES if we are
+   * in the 'waiting_map', #GNUNET_NO if we are in the 'pending' DLL.
    */
   int was_transmitted;
 };
@@ -115,15 +115,15 @@ struct MeshHandle
   struct GSF_MeshRequest *pending_tail;
 
   /**
-   * Map from query to 'struct GSF_MeshRequest's waiting for
+   * Map from query to `struct GSF_MeshRequest`s waiting for
    * a reply.
    */
   struct GNUNET_CONTAINER_MultiHashMap *waiting_map;
 
   /**
-   * Tunnel to the other peer.
+   * Channel to the other peer.
    */
-  struct GNUNET_MESH_Tunnel *tunnel;
+  struct GNUNET_MESH_Channel *channel;
 
   /**
    * Handle for active write operation, or NULL.
@@ -153,13 +153,13 @@ struct MeshHandle
 
 
 /**
- * Mesh tunnel for creating outbound tunnels.
+ * Mesh channel for creating outbound channels.
  */
 static struct GNUNET_MESH_Handle *mesh_handle;
 
 /**
  * Map from peer identities to 'struct MeshHandles' with mesh
- * tunnels to those peers.
+ * channels to those peers.
  */
 static struct GNUNET_CONTAINER_MultiPeerMap *mesh_map;
 
@@ -180,10 +180,10 @@ transmit_pending (struct MeshHandle *mh);
  * Iterator called on each entry in a waiting map to
  * move it back to the pending list.
  *
- * @param cls the 'struct MeshHandle'
+ * @param cls the `struct MeshHandle`
  * @param key the key of the entry in the map (the query)
- * @param value the 'struct GSF_MeshRequest' to move to pending
- * @return GNUNET_YES (continue to iterate)
+ * @param value the `struct GSF_MeshRequest` to move to pending
+ * @return #GNUNET_YES (continue to iterate)
  */
 static int
 move_to_pending (void *cls,
@@ -213,27 +213,30 @@ move_to_pending (void *cls,
 static void
 reset_mesh (struct MeshHandle *mh)
 {
+  struct GNUNET_MESH_Channel *channel = mh->channel;
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Resetting mesh tunnel to %s\n",
+             "Resetting mesh channel to %s\n",
              GNUNET_i2s (&mh->target));
-  GNUNET_MESH_tunnel_destroy (mh->tunnel);
+  mh->channel = NULL;
+  if (NULL != channel)
+    GNUNET_MESH_channel_destroy (channel);
   GNUNET_CONTAINER_multihashmap_iterate (mh->waiting_map,
                                         &move_to_pending,
                                         mh);
-  mh->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
+  mh->channel = GNUNET_MESH_channel_create (mesh_handle,
                                          mh,
                                          &mh->target,
                                          GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
-                                         GNUNET_NO,
-                                         GNUNET_YES);
+                                         GNUNET_MESH_OPTION_RELIABLE);
   transmit_pending (mh);
 }
 
 
 /**
- * Task called when it is time to destroy an inactive mesh tunnel.
+ * Task called when it is time to destroy an inactive mesh channel.
  *
- * @param cls the 'struct MeshHandle' to tear down
+ * @param cls the `struct MeshHandle` to tear down
  * @param tc scheduler context, unused
  */
 static void
@@ -241,22 +244,22 @@ mesh_timeout (void *cls,
              const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct MeshHandle *mh = cls;
-  struct GNUNET_MESH_Tunnel *tun;
+  struct GNUNET_MESH_Channel *tun;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Timeout on mesh tunnel to %s\n",
+             "Timeout on mesh channel to %s\n",
              GNUNET_i2s (&mh->target));
   mh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
-  tun = mh->tunnel;
-  mh->tunnel = NULL;
-  GNUNET_MESH_tunnel_destroy (tun);
+  tun = mh->channel;
+  mh->channel = NULL;
+  GNUNET_MESH_channel_destroy (tun);
 }
 
 
 /**
  * Task called when it is time to reset an mesh.
  *
- * @param cls the 'struct MeshHandle' to tear down
+ * @param cls the `struct MeshHandle` to tear down
  * @param tc scheduler context, unused
  */
 static void
@@ -291,9 +294,9 @@ reset_mesh_async (struct MeshHandle *mh)
  * query via a mesh.
  *
  * @param cls the struct MeshHandle for which we did the write call
- * @param size the number of bytes that can be written to 'buf'
+ * @param size the number of bytes that can be written to @a buf
  * @param buf where to write the message
- * @return number of bytes written to 'buf'
+ * @return number of bytes written to @a buf
  */
 static size_t
 transmit_sqm (void *cls,
@@ -308,7 +311,7 @@ transmit_sqm (void *cls,
   if (NULL == buf)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-               "Mesh tunnel to %s failed during transmission attempt, rebuilding\n",
+               "Mesh channel to %s failed during transmission attempt, rebuilding\n",
                GNUNET_i2s (&mh->target));
     reset_mesh_async (mh);
     return 0;
@@ -342,7 +345,7 @@ transmit_sqm (void *cls,
   transmit_pending (mh);
   return sizeof (sqm);
 }
-       
+
 
 /**
  * Transmit pending requests via the mesh.
@@ -352,11 +355,11 @@ transmit_sqm (void *cls,
 static void
 transmit_pending (struct MeshHandle *mh)
 {
-  if (NULL == mh->tunnel)
+  if (NULL == mh->channel)
     return;
   if (NULL != mh->wh)
     return;
-  mh->wh = GNUNET_MESH_notify_transmit_ready (mh->tunnel, GNUNET_YES /* allow cork */,
+  mh->wh = GNUNET_MESH_notify_transmit_ready (mh->channel, GNUNET_YES /* allow cork */,
                                              GNUNET_TIME_UNIT_FOREVER_REL,
                                              sizeof (struct MeshQueryMessage),
                                              &transmit_sqm, mh);
@@ -364,7 +367,7 @@ transmit_pending (struct MeshHandle *mh)
 
 
 /**
- * Closure for 'handle_reply'.
+ * Closure for handle_reply().
  */
 struct HandleReplyClosure
 {
@@ -400,10 +403,10 @@ struct HandleReplyClosure
  * Iterator called on each entry in a waiting map to
  * process a result.
  *
- * @param cls the 'struct HandleReplyClosure'
+ * @param cls the `struct HandleReplyClosure`
  * @param key the key of the entry in the map (the query)
- * @param value the 'struct GSF_MeshRequest' to handle result for
- * @return GNUNET_YES (continue to iterate)
+ * @param value the `struct GSF_MeshRequest` to handle result for
+ * @return #GNUNET_YES (continue to iterate)
  */
 static int
 handle_reply (void *cls,
@@ -418,6 +421,7 @@ handle_reply (void *cls,
            hrc->expiration,
            hrc->data_size,
            hrc->data);
+  sr->proc = NULL;
   GSF_mesh_query_cancel (sr);
   hrc->found = GNUNET_YES;
   return GNUNET_YES;
@@ -428,19 +432,19 @@ handle_reply (void *cls,
  * Functions with this signature are called whenever a complete reply
  * is received.
  *
- * @param cls closure with the 'struct MeshHandle'
- * @param tunnel tunnel handle
- * @param tunnel_ctx tunnel context
+ * @param cls closure with the `struct MeshHandle`
+ * @param channel channel handle
+ * @param channel_ctx channel context
  * @param message the actual message
- * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
  */
 static int
 reply_cb (void *cls,
-         struct GNUNET_MESH_Tunnel *tunnel,
-         void **tunnel_ctx,
+         struct GNUNET_MESH_Channel *channel,
+         void **channel_ctx,
           const struct GNUNET_MessageHeader *message)
 {
-  struct MeshHandle *mh = *tunnel_ctx;
+  struct MeshHandle *mh = *channel_ctx;
   const struct MeshReplyMessage *srm;
   struct HandleReplyClosure hrc;
   uint16_t msize;
@@ -463,6 +467,11 @@ reply_cb (void *cls,
                            &srm[1], msize, &query))
   {
     GNUNET_break_op (0);
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Received bogus reply of type %u with %u bytes via mesh from peer %s\n",
+                type,
+                msize,
+                GNUNET_i2s (&mh->target));
     reset_mesh_async (mh);
     return GNUNET_SYSERR;
   }
@@ -470,7 +479,7 @@ reply_cb (void *cls,
              "Received reply `%s' via mesh from peer %s\n",
              GNUNET_h2s (&query),
              GNUNET_i2s (&mh->target));
-  GNUNET_MESH_receive_done (tunnel);
+  GNUNET_MESH_receive_done (channel);
   GNUNET_STATISTICS_update (GSF_stats,
                            gettext_noop ("# replies received via mesh"), 1,
                            GNUNET_NO);
@@ -516,7 +525,7 @@ get_mesh (const struct GNUNET_PeerIdentity *target)
     return mh;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Creating mesh tunnel to %s\n",
+             "Creating mesh channel to %s\n",
              GNUNET_i2s (target));
   mh = GNUNET_new (struct MeshHandle);
   mh->reset_task = GNUNET_SCHEDULER_add_delayed (CLIENT_RETRY_TIMEOUT,
@@ -524,17 +533,19 @@ get_mesh (const struct GNUNET_PeerIdentity *target)
                                                 mh);
   mh->waiting_map = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES);
   mh->target = *target;
-  mh->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
-                                         mh,
-                                         &mh->target,
-                                         GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
-                                         GNUNET_NO,
-                                         GNUNET_YES);
   GNUNET_assert (GNUNET_OK ==
                 GNUNET_CONTAINER_multipeermap_put (mesh_map,
                                                    &mh->target,
                                                    mh,
                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+  mh->channel = GNUNET_MESH_channel_create (mesh_handle,
+                                            mh,
+                                            &mh->target,
+                                            GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
+                                            GNUNET_MESH_OPTION_RELIABLE);
+  GNUNET_assert (mh ==
+                 GNUNET_CONTAINER_multipeermap_get (mesh_map,
+                                                    target));
   return mh;
 }
 
@@ -546,7 +557,7 @@ get_mesh (const struct GNUNET_PeerIdentity *target)
  * @param query hash to query for the block
  * @param type desired type for the block
  * @param proc function to call with result
- * @param proc_cls closure for 'proc'
+ * @param proc_cls closure for @a proc
  * @return handle to cancel the operation
  */
 struct GSF_MeshRequest *
@@ -587,7 +598,17 @@ void
 GSF_mesh_query_cancel (struct GSF_MeshRequest *sr)
 {
   struct MeshHandle *mh = sr->mh;
+  GSF_MeshReplyProcessor p;
 
+  p = sr->proc;
+  sr->proc = NULL;
+  if (NULL != p)
+  {
+    /* signal failure / cancellation to callback */
+    p (sr->proc_cls, GNUNET_BLOCK_TYPE_ANY,
+       GNUNET_TIME_UNIT_ZERO_ABS,
+       0, NULL);
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Cancelled query for %s via mesh to %s\n",
              GNUNET_h2s (&sr->query),
@@ -615,10 +636,10 @@ GSF_mesh_query_cancel (struct GSF_MeshRequest *sr)
  * call the 'proc' continuation and release associated
  * resources.
  *
- * @param cls the 'struct MeshHandle'
+ * @param cls the `struct MeshHandle`
  * @param key the key of the entry in the map (the query)
- * @param value the 'struct GSF_MeshRequest' to clean up
- * @return GNUNET_YES (continue to iterate)
+ * @param value the `struct GSF_MeshRequest` to clean up
+ * @return #GNUNET_YES (continue to iterate)
  */
 static int
 free_waiting_entry (void *cls,
@@ -627,9 +648,6 @@ free_waiting_entry (void *cls,
 {
   struct GSF_MeshRequest *sr = value;
 
-  sr->proc (sr->proc_cls, GNUNET_BLOCK_TYPE_ANY,
-           GNUNET_TIME_UNIT_FOREVER_ABS,
-           0, NULL);
   GSF_mesh_query_cancel (sr);
   return GNUNET_YES;
 }
@@ -637,28 +655,34 @@ free_waiting_entry (void *cls,
 
 /**
  * Function called by mesh when a client disconnects.
- * Cleans up our 'struct MeshClient' of that tunnel.
+ * Cleans up our `struct MeshClient` of that channel.
  *
  * @param cls NULL
- * @param tunnel tunnel of the disconnecting client
- * @param tunnel_ctx our 'struct MeshClient'
+ * @param channel channel of the disconnecting client
+ * @param channel_ctx our `struct MeshClient`
  */
 static void
 cleaner_cb (void *cls,
-           const struct GNUNET_MESH_Tunnel *tunnel,
-           void *tunnel_ctx)
+           const struct GNUNET_MESH_Channel *channel,
+           void *channel_ctx)
 {
-  struct MeshHandle *mh = tunnel_ctx;
+  struct MeshHandle *mh = channel_ctx;
   struct GSF_MeshRequest *sr;
 
-  mh->tunnel = NULL;
+  if (NULL == mh->channel)
+    return; /* being destroyed elsewhere */
+  GNUNET_assert (channel == mh->channel);
+  mh->channel = NULL;
   while (NULL != (sr = mh->pending_head))
-  {
-    sr->proc (sr->proc_cls, GNUNET_BLOCK_TYPE_ANY,
-             GNUNET_TIME_UNIT_FOREVER_ABS,
-             0, NULL);
     GSF_mesh_query_cancel (sr);
-  }
+  /* first remove `mh` from the `mesh_map`, so that if the
+     callback from `free_waiting_entry()` happens to re-issue
+     the request, we don't immediately have it back in the
+     `waiting_map`. */
+  GNUNET_assert (GNUNET_OK ==
+                GNUNET_CONTAINER_multipeermap_remove (mesh_map,
+                                                      &mh->target,
+                                                      mh));
   GNUNET_CONTAINER_multihashmap_iterate (mh->waiting_map,
                                         &free_waiting_entry,
                                         mh);
@@ -668,10 +692,8 @@ cleaner_cb (void *cls,
     GNUNET_SCHEDULER_cancel (mh->timeout_task);
   if (GNUNET_SCHEDULER_NO_TASK != mh->reset_task)
     GNUNET_SCHEDULER_cancel (mh->reset_task);
-  GNUNET_assert (GNUNET_OK ==
-                GNUNET_CONTAINER_multipeermap_remove (mesh_map,
-                                                      &mh->target,
-                                                      mh));
+  GNUNET_assert (0 ==
+                 GNUNET_CONTAINER_multihashmap_size (mh->waiting_map));
   GNUNET_CONTAINER_multihashmap_destroy (mh->waiting_map);
   GNUNET_free (mh);
 }
@@ -703,8 +725,8 @@ GSF_mesh_start_client ()
  *
  * @param cls NULL
  * @param key target peer, unused
- * @param value the 'struct MeshHandle' to destroy
- * @return GNUNET_YES (continue to iterate)
+ * @param value the `struct MeshHandle` to destroy
+ * @return #GNUNET_YES (continue to iterate)
  */
 static int
 release_meshs (void *cls,
@@ -712,15 +734,12 @@ release_meshs (void *cls,
               void *value)
 {
   struct MeshHandle *mh = value;
-  struct GNUNET_MESH_Tunnel *tun;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Timeout on mesh tunnel to %s\n",
+             "Timeout on mesh channel to %s\n",
              GNUNET_i2s (&mh->target));
-  tun = mh->tunnel;
-  mh->tunnel = NULL;
-  if (NULL != tun)
-    GNUNET_MESH_tunnel_destroy (tun);
+  if (NULL != mh->channel)
+    GNUNET_MESH_channel_destroy (mh->channel);
   return GNUNET_YES;
 }