fix more leaks
[oweals/gnunet.git] / src / fs / gnunet-service-fs_mesh_client.c
index 06668a46e3bd6a722e7e552db8869771cb1d2198..73ab6bb5d7c821e49b21dc791cd798b1fe2af358 100644 (file)
@@ -44,7 +44,7 @@
 #define CLIENT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
 
 
-/** 
+/**
  * Handle for a mesh to another peer.
  */
 struct MeshHandle;
@@ -93,13 +93,13 @@ struct GSF_MeshRequest
 
   /**
    * Did we transmit this request already? YES if we are
-   * in the 'waiting' DLL, NO if we are in the 'pending' DLL.
+   * in the 'waiting_map', NO if we are in the 'pending' DLL.
    */
   int was_transmitted;
 };
 
 
-/** 
+/**
  * Handle for a mesh to another peer.
  */
 struct MeshHandle
@@ -127,12 +127,12 @@ struct MeshHandle
 
   /**
    * Handle for active write operation, or NULL.
-   */ 
+   */
   struct GNUNET_MESH_TransmitHandle *wh;
 
   /**
    * Which peer does this mesh go to?
-   */ 
+   */
   struct GNUNET_PeerIdentity target;
 
   /**
@@ -155,13 +155,13 @@ struct MeshHandle
 /**
  * Mesh tunnel for creating outbound tunnels.
  */
-static struct GNUNET_MESH_Handle *mesh_tunnel;
+static struct GNUNET_MESH_Handle *mesh_handle;
 
 /**
  * Map from peer identities to 'struct MeshHandles' with mesh
  * tunnels to those peers.
  */
-static struct GNUNET_CONTAINER_MultiHashMap *mesh_map;
+static struct GNUNET_CONTAINER_MultiPeerMap *mesh_map;
 
 
 /* ********************* client-side code ************************* */
@@ -177,7 +177,7 @@ transmit_pending (struct MeshHandle *mh);
 
 
 /**
- * Iterator called on each entry in a waiting map to 
+ * Iterator called on each entry in a waiting map to
  * move it back to the pending list.
  *
  * @param cls the 'struct MeshHandle'
@@ -192,7 +192,7 @@ move_to_pending (void *cls,
 {
   struct MeshHandle *mh = cls;
   struct GSF_MeshRequest *sr = value;
-  
+
   GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap_remove (mh->waiting_map,
                                                       key,
@@ -220,12 +220,13 @@ reset_mesh (struct MeshHandle *mh)
   GNUNET_CONTAINER_multihashmap_iterate (mh->waiting_map,
                                         &move_to_pending,
                                         mh);
-  mh->tunnel = GNUNET_MESH_tunnel_create (mesh_tunnel,
-                                       mh,
-                                       &mh->target,
-                                       GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
-                                       GNUNET_YES,
-                                       GNUNET_YES);
+  mh->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
+                                         mh,
+                                         &mh->target,
+                                         GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
+                                         GNUNET_NO,
+                                         GNUNET_YES);
+  transmit_pending (mh);
 }
 
 
@@ -306,7 +307,10 @@ transmit_sqm (void *cls,
   mh->wh = NULL;
   if (NULL == buf)
   {
-    reset_mesh (mh);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Mesh tunnel to %s failed during transmission attempt, rebuilding\n",
+               GNUNET_i2s (&mh->target));
+    reset_mesh_async (mh);
     return 0;
   }
   sr = mh->pending_head;
@@ -316,15 +320,16 @@ transmit_sqm (void *cls,
   GNUNET_CONTAINER_DLL_remove (mh->pending_head,
                               mh->pending_tail,
                               sr);
-  GNUNET_CONTAINER_multihashmap_put (mh->waiting_map,
-                                    &sr->query,
-                                    sr,
-                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+  GNUNET_assert (GNUNET_OK ==
+                GNUNET_CONTAINER_multihashmap_put (mh->waiting_map,
+                                                   &sr->query,
+                                                   sr,
+                                                   GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
+  sr->was_transmitted = GNUNET_YES;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Sending query for %s via mesh to %s\n",
              GNUNET_h2s (&sr->query),
              GNUNET_i2s (&mh->target));
-  sr->was_transmitted = GNUNET_YES;
   sqm.header.size = htons (sizeof (sqm));
   sqm.header.type = htons (GNUNET_MESSAGE_TYPE_FS_MESH_QUERY);
   sqm.type = htonl (sr->type);
@@ -337,7 +342,7 @@ transmit_sqm (void *cls,
   transmit_pending (mh);
   return sizeof (sqm);
 }
-         
+       
 
 /**
  * Transmit pending requests via the mesh.
@@ -347,6 +352,8 @@ transmit_sqm (void *cls,
 static void
 transmit_pending (struct MeshHandle *mh)
 {
+  if (NULL == mh->tunnel)
+    return;
   if (NULL != mh->wh)
     return;
   mh->wh = GNUNET_MESH_notify_transmit_ready (mh->tunnel, GNUNET_YES /* allow cork */,
@@ -364,7 +371,7 @@ struct HandleReplyClosure
 
   /**
    * Reply payload.
-   */ 
+   */
   const void *data;
 
   /**
@@ -377,11 +384,11 @@ struct HandleReplyClosure
    */
   size_t data_size;
 
-  /** 
+  /**
    * Type of the block.
    */
   enum GNUNET_BLOCK_Type type;
-  
+
   /**
    * Did we have a matching query?
    */
@@ -390,7 +397,7 @@ struct HandleReplyClosure
 
 
 /**
- * Iterator called on each entry in a waiting map to 
+ * Iterator called on each entry in a waiting map to
  * process a result.
  *
  * @param cls the 'struct HandleReplyClosure'
@@ -405,7 +412,7 @@ handle_reply (void *cls,
 {
   struct HandleReplyClosure *hrc = cls;
   struct GSF_MeshRequest *sr = value;
-  
+
   sr->proc (sr->proc_cls,
            hrc->type,
            hrc->expiration,
@@ -455,7 +462,7 @@ reply_cb (void *cls,
                            type,
                            &srm[1], msize, &query))
   {
-    GNUNET_break_op (0); 
+    GNUNET_break_op (0);
     reset_mesh_async (mh);
     return GNUNET_SYSERR;
   }
@@ -463,6 +470,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_STATISTICS_update (GSF_stats,
                            gettext_noop ("# replies received via mesh"), 1,
                            GNUNET_NO);
@@ -496,8 +504,8 @@ get_mesh (const struct GNUNET_PeerIdentity *target)
 {
   struct MeshHandle *mh;
 
-  mh = GNUNET_CONTAINER_multihashmap_get (mesh_map,
-                                         &target->hashPubKey);
+  mh = GNUNET_CONTAINER_multipeermap_get (mesh_map,
+                                         target);
   if (NULL != mh)
   {
     if (GNUNET_SCHEDULER_NO_TASK != mh->timeout_task)
@@ -516,15 +524,15 @@ 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_tunnel,
-                                       mh,
-                                       &mh->target,
-                                       GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
-                                       GNUNET_NO,
-                                       GNUNET_YES);
+  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_multihashmap_put (mesh_map,
-                                                   &mh->target.hashPubKey,
+                GNUNET_CONTAINER_multipeermap_put (mesh_map,
+                                                   &mh->target,
                                                    mh,
                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
   return mh;
@@ -603,7 +611,7 @@ GSF_mesh_query_cancel (struct GSF_MeshRequest *sr)
 
 
 /**
- * Iterator called on each entry in a waiting map to 
+ * Iterator called on each entry in a waiting map to
  * call the 'proc' continuation and release associated
  * resources.
  *
@@ -633,7 +641,7 @@ free_waiting_entry (void *cls,
  *
  * @param cls NULL
  * @param tunnel tunnel of the disconnecting client
- * @param tunnel_ctx our 'struct MeshClient' 
+ * @param tunnel_ctx our 'struct MeshClient'
  */
 static void
 cleaner_cb (void *cls,
@@ -661,8 +669,8 @@ cleaner_cb (void *cls,
   if (GNUNET_SCHEDULER_NO_TASK != mh->reset_task)
     GNUNET_SCHEDULER_cancel (mh->reset_task);
   GNUNET_assert (GNUNET_OK ==
-                GNUNET_CONTAINER_multihashmap_remove (mesh_map,
-                                                      &mh->target.hashPubKey,
+                GNUNET_CONTAINER_multipeermap_remove (mesh_map,
+                                                      &mh->target,
                                                       mh));
   GNUNET_CONTAINER_multihashmap_destroy (mh->waiting_map);
   GNUNET_free (mh);
@@ -679,18 +687,14 @@ GSF_mesh_start_client ()
     { &reply_cb, GNUNET_MESSAGE_TYPE_FS_MESH_REPLY, 0 },
     { NULL, 0, 0 }
   };
-  static const uint32_t ports[] = {
-    GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
-    0
-  };
 
-  mesh_map = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES);
-  mesh_tunnel = GNUNET_MESH_connect (GSF_cfg,
-                                        NULL,
-                                        NULL,
-                                        &cleaner_cb,
-                                        handlers,
-                                        ports);
+  mesh_map = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
+  mesh_handle = GNUNET_MESH_connect (GSF_cfg,
+                                    NULL,
+                                    NULL,
+                                    &cleaner_cb,
+                                    handlers,
+                                    NULL);
 }
 
 
@@ -704,7 +708,7 @@ GSF_mesh_start_client ()
  */
 static int
 release_meshs (void *cls,
-              const struct GNUNET_HashCode *key,
+              const struct GNUNET_PeerIdentity *key,
               void *value)
 {
   struct MeshHandle *mh = value;
@@ -727,15 +731,15 @@ release_meshs (void *cls,
 void
 GSF_mesh_stop_client ()
 {
-  GNUNET_CONTAINER_multihashmap_iterate (mesh_map,
+  GNUNET_CONTAINER_multipeermap_iterate (mesh_map,
                                         &release_meshs,
                                         NULL);
-  GNUNET_CONTAINER_multihashmap_destroy (mesh_map);
+  GNUNET_CONTAINER_multipeermap_destroy (mesh_map);
   mesh_map = NULL;
-  if (NULL != mesh_tunnel)
+  if (NULL != mesh_handle)
   {
-    GNUNET_MESH_disconnect (mesh_tunnel);
-    mesh_tunnel = NULL;
+    GNUNET_MESH_disconnect (mesh_handle);
+    mesh_handle = NULL;
   }
 }