-options to play with
[oweals/gnunet.git] / src / fs / gnunet-service-fs_pr.c
index 6acc0e2bf1967e33c979c961b7dfd87ab2b42354..76e04f57cf5684b60caecc564e69ca2d423ab0cd 100644 (file)
  */
 #define INSANE_STATISTICS GNUNET_NO
 
+/**
+ * If obtaining a block via stream fails, how often do we retry it before
+ * giving up for good (and sticking to non-anonymous transfer)?
+ */
+#define STREAM_RETRY_MAX 3
+
+
 /**
  * An active request.
  */
@@ -165,6 +172,12 @@ struct GSF_PendingRequest
    */
   uint64_t first_uid;
 
+  /**
+   * How often have we retried this request via 'stream'?
+   * (used to bound overall retries).
+   */
+  unsigned int stream_retry_count;
+
   /**
    * Number of valid entries in the 'replies_seen' array.
    */
@@ -1175,11 +1188,32 @@ stream_reply_proc (void *cls,
   struct GNUNET_HashCode query;
 
   pr->stream_request = NULL;
+  if (GNUNET_BLOCK_TYPE_ANY == type)
+  {
+    GNUNET_break (NULL == data);
+    GNUNET_break (0 == data_size);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Error retrieiving block via stream\n");
+    pr->stream_retry_count++;
+    if (pr->stream_retry_count >= STREAM_RETRY_MAX)
+      return; /* give up on stream */
+    /* retry -- without delay, as this is non-anonymous
+       and mesh/stream connect will take some time anyway */
+    pr->stream_request = GSF_stream_query (pr->public_data.target,
+                                          &pr->public_data.query,
+                                          pr->public_data.type,
+                                          &stream_reply_proc,
+                                          pr);
+    return;
+  }
   if (GNUNET_YES !=
       GNUNET_BLOCK_get_key (GSF_block_ctx,
                            type,
                            data, data_size, &query))
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Failed to derive key for block of type %d\n",
+               (int) type);
     GNUNET_break_op (0);
     return;
   }
@@ -1209,7 +1243,11 @@ GSF_stream_lookup_ (struct GSF_PendingRequest *pr)
   if (0 != pr->public_data.anonymity_level)
     return;
   if (0 == pr->public_data.target)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Cannot do stream-based download, target peer not known\n");
     return;
+  }
   if (NULL != pr->stream_request)
     return;
   pr->stream_request = GSF_stream_query (pr->public_data.target,