GNUnet  0.10.x
Data Structures | Macros | Functions
fs_download.c File Reference

download methods More...

#include "platform.h"
#include "gnunet_constants.h"
#include "gnunet_fs_service.h"
#include "fs_api.h"
#include "fs_tree.h"
Include dependency graph for fs_download.c:

Go to the source code of this file.

Data Structures

struct  ProcessResultClosure
 Closure for iterator processing results. More...
 

Macros

#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX
 

Functions

static int is_recursive_download (struct GNUNET_FS_DownloadContext *dc)
 Determine if the given download (options and meta data) should cause use to try to do a recursive download. More...
 
static uint64_t compute_disk_offset (uint64_t fsize, uint64_t off, unsigned int depth)
 We're storing the IBLOCKS after the DBLOCKS on disk (so that we only have to truncate the file once we're done). More...
 
void GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
 Fill in all of the generic fields for a download event and call the callback. More...
 
static int process_result_with_request (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over entries in the pending requests in the 'active' map for the reply that we just got. More...
 
static int encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, const struct ContentHashKey *chk, struct DownloadRequest *dr, const char *block, size_t len, int do_store)
 We've found a matching block without downloading it. More...
 
static void try_reconnect (struct GNUNET_FS_DownloadContext *dc)
 We've lost our connection with the FS service. More...
 
static void trigger_recursive_download (void *cls, const char *filename, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, size_t length, const void *data)
 We found an entry in a directory. More...
 
static void full_recursive_download (struct GNUNET_FS_DownloadContext *dc)
 We're done downloading a directory. More...
 
static void check_completed (struct GNUNET_FS_DownloadContext *dc)
 Check if all child-downloads have completed (or trigger them if necessary) and once we're completely done, signal completion (and possibly recurse to parent). More...
 
static void try_match_block (struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr, const char *data, size_t data_len)
 We got a block of plaintext data (from the meta data). More...
 
static int match_full_data (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len)
 Type of a function that libextractor calls for each meta data item found. More...
 
static void propagate_up (struct DownloadRequest *dr)
 Set the state of the given download request to BRS_DOWNLOAD_UP and propagate it up the tree. More...
 
static void try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
 Try top-down reconstruction. More...
 
static int retry_entry (void *cls, const struct GNUNET_HashCode *key, void *entry)
 Add entries to the message queue. More...
 
static void schedule_block_download (struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
 Schedule the download of the specified block in the tree. More...
 
void GNUNET_FS_free_download_request_ (struct DownloadRequest *dr)
 (recursively) free download request structure More...
 
static int check_put (void *cls, const struct ClientPutMessage *cm)
 Type of a function to call when we check the PUT message from the service. More...
 
static void handle_put (void *cls, const struct ClientPutMessage *cm)
 Type of a function to call when we receive a message from the service. More...
 
static void download_mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
 Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue. More...
 
static void do_reconnect (void *cls)
 Reconnect to the FS service and transmit our queries NOW. More...
 
static void activate_fs_download (void *cls)
 We're allowed to ask the FS service for our blocks. More...
 
static void deactivate_fs_download (void *cls)
 We must stop to ask the FS service for our blocks. More...
 
static struct DownloadRequestcreate_download_request (struct DownloadRequest *parent, unsigned int chk_idx, unsigned int depth, uint64_t dr_offset, uint64_t file_start_offset, uint64_t desired_length)
 (recursively) Create a download request structure. More...
 
static void reconstruct_cont (void *cls)
 Continuation after a possible attempt to reconstruct the current IBlock from the existing file. More...
 
static void get_next_block (void *cls)
 Task requesting the next block from the tree encoder. More...
 
static void reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, unsigned int depth, enum GNUNET_BLOCK_Type type, const void *block, uint16_t block_size)
 Function called asking for the current (encoded) block to be processed. More...
 
static size_t fh_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
 Function called by the tree encoder to obtain a block of plaintext data (for the lowest level of the tree). More...
 
void GNUNET_FS_download_start_task_ (void *cls)
 Task that creates the initial (top-level) download request for the file. More...
 
void GNUNET_FS_download_signal_suspend_ (void *cls)
 Create SUSPEND event for the given download operation and then clean up our state (without stop signal). More...
 
struct GNUNET_FS_DownloadContextcreate_download_context (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, const char *filename, const char *tempname, uint64_t offset, uint64_t length, uint32_t anonymity, enum GNUNET_FS_DownloadOptions options, void *cctx)
 Helper function to setup the download context. More...
 
struct GNUNET_FS_DownloadContextGNUNET_FS_download_start (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, const char *filename, const char *tempname, uint64_t offset, uint64_t length, uint32_t anonymity, enum GNUNET_FS_DownloadOptions options, void *cctx, struct GNUNET_FS_DownloadContext *parent)
 Download parts of a file. More...
 
struct GNUNET_FS_DownloadContextGNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, struct GNUNET_FS_SearchResult *sr, const char *filename, const char *tempname, uint64_t offset, uint64_t length, uint32_t anonymity, enum GNUNET_FS_DownloadOptions options, void *cctx)
 Download parts of a file based on a search result. More...
 
void GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc)
 Start the downloading process (by entering the queue). More...
 
void GNUNET_FS_download_suspend (struct GNUNET_FS_DownloadContext *dc)
 Suspend a download. More...
 
void GNUNET_FS_download_resume (struct GNUNET_FS_DownloadContext *dc)
 Resume a suspended download. More...
 
void GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete)
 Stop a download (aborts if download is incomplete). More...
 

Detailed Description

download methods

Author
Christian Grothoff

Definition in file fs_download.c.

Macro Definition Documentation

◆ GNUNET_FS_URI_CHK_PREFIX

#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX

Definition at line 837 of file fs_download.c.

Referenced by trigger_recursive_download().

Function Documentation

◆ is_recursive_download()

static int is_recursive_download ( struct GNUNET_FS_DownloadContext dc)
static

Determine if the given download (options and meta data) should cause use to try to do a recursive download.

Definition at line 37 of file fs_download.c.

References GNUNET_FS_DownloadContext::filename, GNUNET_FS_DIRECTORY_EXT, GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE, GNUNET_FS_meta_data_test_for_directory(), GNUNET_YES, GNUNET_FS_DownloadContext::meta, and GNUNET_FS_DownloadContext::options.

Referenced by check_completed(), create_download_context(), and process_result_with_request().

38 {
39  return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) &&
40  ( (GNUNET_YES ==
42  ( (NULL == dc->meta) &&
43  ( (NULL == dc->filename) ||
44  ( (strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
45  (NULL !=
46  strstr (dc->filename + strlen (dc->filename) -
47  strlen (GNUNET_FS_DIRECTORY_EXT),
48  GNUNET_FS_DIRECTORY_EXT)) ) ) ) );
49 }
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition: fs_api.h:1949
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_FS_DIRECTORY_EXT
int GNUNET_FS_meta_data_test_for_directory(const struct GNUNET_CONTAINER_MetaData *md)
Does the meta-data claim that this is a directory? Checks if the mime-type is that of a GNUnet direct...
Definition: fs_directory.c:54
Do a recursive download (that is, automatically trigger the download of files in directories).
struct GNUNET_CONTAINER_MetaData * meta
Known meta-data for the file (can be NULL).
Definition: fs_api.h:1831
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ compute_disk_offset()

static uint64_t compute_disk_offset ( uint64_t  fsize,
uint64_t  off,
unsigned int  depth 
)
static

We're storing the IBLOCKS after the DBLOCKS on disk (so that we only have to truncate the file once we're done).

Given the offset of a block (with respect to the DBLOCKS) and its depth, return the offset where we would store this block in the file.

Parameters
fsizeoverall file size
offoffset of the block in the file
depthdepth of the block in the tree, 0 for DBLOCK
Returns
off for DBLOCKS (depth == treedepth), otherwise an offset past the end of the file that does not overlap with the range for any other block

Definition at line 69 of file fs_download.c.

References CHK_PER_INODE, DBLOCK_SIZE, and GNUNET_assert.

Referenced by process_result_with_request(), and try_top_down_reconstruction().

70 {
71  unsigned int i;
72  uint64_t lsize; /* what is the size of all IBlocks for depth "i"? */
73  uint64_t loff; /* where do IBlocks for depth "i" start? */
74  unsigned int ioff; /* which IBlock corresponds to "off" at depth "i"? */
75 
76  if (0 == depth)
77  return off;
78  /* first IBlocks start at the end of file, rounded up
79  * to full DBLOCK_SIZE */
80  loff = ((fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * DBLOCK_SIZE;
81  lsize =
82  ((fsize + DBLOCK_SIZE -
83  1) / DBLOCK_SIZE) * sizeof (struct ContentHashKey);
84  GNUNET_assert (0 == (off % DBLOCK_SIZE));
85  ioff = (off / DBLOCK_SIZE);
86  for (i = 1; i < depth; i++)
87  {
88  loff += lsize;
89  lsize = (lsize + CHK_PER_INODE - 1) / CHK_PER_INODE;
90  GNUNET_assert (lsize > 0);
91  GNUNET_assert (0 == (ioff % CHK_PER_INODE));
92  ioff /= CHK_PER_INODE;
93  }
94  return loff + ioff * sizeof (struct ContentHashKey);
95 }
content hash key
Definition: fs.h:53
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define CHK_PER_INODE
Pick a multiple of 2 here to achive 8-byte alignment! We also probably want DBlocks to have (roughly)...
Definition: fs_api.h:43
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
Here is the caller graph for this function:

◆ GNUNET_FS_download_make_status_()

void GNUNET_FS_download_make_status_ ( struct GNUNET_FS_ProgressInfo pi,
struct GNUNET_FS_DownloadContext dc 
)

Fill in all of the generic fields for a download event and call the callback.

Parameters
pistructure to fill in
dcoverall download context

Definition at line 106 of file fs_download.c.

References GNUNET_FS_DownloadContext::anonymity, GNUNET_FS_SearchResult::client_info, GNUNET_FS_DownloadContext::client_info, GNUNET_FS_DownloadContext::completed, dc, GNUNET_FS_ProgressInfo::download, GNUNET_FS_DownloadContext::filename, GNUNET_FS_ProgressInfo::fsh, GNUNET_FS_DOWNLOAD_IS_PROBE, GNUNET_FS_search_probe_progress_(), GNUNET_NO, GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_calculate_eta(), GNUNET_YES, GNUNET_FS_DownloadContext::h, GNUNET_FS_DownloadContext::length, GNUNET_FS_DownloadContext::mq, GNUNET_FS_DownloadContext::options, GNUNET_FS_DownloadContext::parent, GNUNET_FS_DownloadContext::search, GNUNET_FS_DownloadContext::start_time, GNUNET_FS_Handle::upcb, GNUNET_FS_Handle::upcb_cls, GNUNET_FS_DownloadContext::uri, and GNUNET_FS_ProgressInfo::value.

Referenced by activate_fs_download(), check_completed(), deactivate_fs_download(), GNUNET_FS_download_resume(), GNUNET_FS_download_signal_suspend_(), GNUNET_FS_download_start_task_(), GNUNET_FS_download_stop(), process_result_with_request(), reconstruct_cb(), search_result_stop(), signal_download_resume(), and try_match_block().

108 {
109  pi->value.download.dc = dc;
110  pi->value.download.cctx = dc->client_info;
111  pi->value.download.pctx =
112  (NULL == dc->parent) ? NULL : dc->parent->client_info;
113  pi->value.download.sctx =
114  (NULL == dc->search) ? NULL : dc->search->client_info;
115  pi->value.download.uri = dc->uri;
116  pi->value.download.filename = dc->filename;
117  pi->value.download.size = dc->length;
118  /* FIXME: Fix duration calculation to account for pauses */
119  pi->value.download.duration =
121  pi->value.download.completed = dc->completed;
122  pi->value.download.anonymity = dc->anonymity;
123  pi->value.download.eta =
125  pi->value.download.is_active = (NULL == dc->mq) ? GNUNET_NO : GNUNET_YES;
126  pi->fsh = dc->h;
127  if (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
128  dc->client_info = dc->h->upcb (dc->h->upcb_cls, pi);
129  else
131 }
void * client_info
Client info for this search result.
Definition: fs_api.h:548
void * GNUNET_FS_search_probe_progress_(void *cls, const struct GNUNET_FS_ProgressInfo *info)
Notification of FS that a search probe has made progress.
Definition: fs_search.c:279
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition: fs_api.h:1949
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
struct GNUNET_FS_ProgressInfo::@28::@30 download
Values for all "GNUNET_FS_STATUS_DOWNLOAD_*" events.
struct GNUNET_FS_DownloadContext * parent
Parent download (used when downloading files in directories).
Definition: fs_api.h:1790
#define GNUNET_NO
Definition: gnunet_common.h:81
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
void * client_info
Context kept for the client.
Definition: fs_api.h:1821
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
union GNUNET_FS_ProgressInfo::@28 value
Values that depend on the event type.
Internal option used to flag this download as a &#39;probe&#39; for a search result.
struct GNUNET_FS_SearchResult * search
Associated search (used when downloading files based on search results), or NULL for none...
Definition: fs_api.h:1796
struct GNUNET_FS_Handle * fsh
File-sharing handle that generated the event.
GNUNET_FS_ProgressCallback upcb
Function to call with updates on our progress.
Definition: fs_api.h:1102
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
void * upcb_cls
Closure for upcb.
Definition: fs_api.h:1107
uint32_t anonymity
Desired level of anonymity.
Definition: fs_api.h:1939
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
struct GNUNET_TIME_Relative GNUNET_TIME_calculate_eta(struct GNUNET_TIME_Absolute start, uint64_t finished, uint64_t total)
Calculate the estimate time of arrival/completion for an operation.
Definition: time.c:549
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_TIME_Absolute start_time
Time download was started.
Definition: fs_api.h:1929
uint64_t completed
How many bytes have we already received within the specified range (DBlocks only).
Definition: fs_api.h:1916
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
static struct GNUNET_FS_DownloadContext * dc
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_result_with_request()

static int process_result_with_request ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Iterator over entries in the pending requests in the 'active' map for the reply that we just got.

Parameters
clsclosure (our 'struct ProcessResultClosure')
keyquery for the given value / request
valuevalue in the hash map (a 'struct DownloadRequest')
Returns
GNUNET_YES (we should continue to iterate); unless serious error
Parameters
clsclosure (our struct ProcessResultClosure)
keyquery for the given value / request
valuevalue in the hash map (a struct DownloadRequest)
Returns
GNUNET_YES (we should continue to iterate); unless serious error

Definition at line 1013 of file fs_download.c.

References _, GNUNET_TIME_Absolute::abs_value_us, GNUNET_FS_DownloadContext::active, BRS_CHK_SET, BRS_DOWNLOAD_DOWN, BRS_DOWNLOAD_UP, BRS_ERROR, BRS_INIT, BRS_RECONSTRUCT_DOWN, BRS_RECONSTRUCT_META_UP, BRS_RECONSTRUCT_UP, check_completed(), DownloadRequest::children, GNUNET_FS_Uri::chk, DownloadRequest::chk, DownloadRequest::chk_idx, GNUNET_FS_DownloadContext::completed, compute_disk_offset(), ProcessResultClosure::data, GNUNET_FS_Uri::data, ProcessResultClosure::dc, DownloadRequest::depth, ProcessResultClosure::do_store, GNUNET_FS_ProgressInfo::download, GNUNET_FS_DownloadContext::emsg, fh, FileIdentifier::file_length, GNUNET_FS_DownloadContext::filename, GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash_to_aes_key(), GNUNET_CRYPTO_symmetric_decrypt(), GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_seek(), GNUNET_DISK_file_write(), GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_GROUP_READ, GNUNET_DISK_PERM_OTHER_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_DISK_SEEK_SET, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_FS_dequeue_(), GNUNET_FS_directory_list_contents(), GNUNET_FS_download_make_status_(), GNUNET_FS_DOWNLOAD_NO_TEMPORARIES, GNUNET_FS_download_sync_(), GNUNET_FS_free_download_request_(), GNUNET_FS_STATUS_DOWNLOAD_ERROR, GNUNET_FS_STATUS_DOWNLOAD_PROGRESS, GNUNET_FS_tree_calculate_block_size(), GNUNET_h2s(), GNUNET_log, GNUNET_log_strerror_file, GNUNET_MQ_destroy(), GNUNET_NO, GNUNET_ntohll(), GNUNET_OK, GNUNET_strdup, GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_ZERO, GNUNET_YES, is_recursive_download(), GNUNET_FS_DownloadContext::issue_requests, GNUNET_FS_DownloadContext::job_queue, ContentHashKey::key, ProcessResultClosure::last_transmission, GNUNET_FS_DownloadContext::length, GNUNET_FS_DownloadContext::mq, DownloadRequest::num_children, ProcessResultClosure::num_transmissions, DownloadRequest::offset, GNUNET_FS_DownloadContext::offset, GNUNET_FS_DownloadContext::options, DownloadRequest::parent, propagate_up(), ProcessResultClosure::query, ProcessResultClosure::respect_offered, schedule_block_download(), ProcessResultClosure::size, DownloadRequest::state, GNUNET_FS_ProgressInfo::status, STRERROR, GNUNET_FS_DownloadContext::temp_filename, GNUNET_FS_DownloadContext::top_request, GNUNET_FS_DownloadContext::treedepth, trigger_recursive_download(), TRUNCATE, GNUNET_FS_DownloadContext::uri, value, and GNUNET_FS_ProgressInfo::value.

Referenced by encrypt_existing_match(), and handle_put().

1016 {
1017  struct ProcessResultClosure *prc = cls;
1018  struct DownloadRequest *dr = value;
1019  struct GNUNET_FS_DownloadContext *dc = prc->dc;
1020  struct DownloadRequest *drc;
1021  struct GNUNET_DISK_FileHandle *fh = NULL;
1024  char pt[prc->size];
1025  struct GNUNET_FS_ProgressInfo pi;
1026  uint64_t off;
1027  size_t bs;
1028  size_t app;
1029  int i;
1030  struct ContentHashKey *chkarr;
1031 
1033  "Received %u byte block `%s' matching pending request at depth %u and offset %llu/%llu\n",
1034  (unsigned int) prc->size,
1035  GNUNET_h2s (key),
1036  dr->depth,
1037  (unsigned long long) dr->offset,
1038  (unsigned long long) GNUNET_ntohll (dc->uri->data.
1039  chk.file_length));
1041  (dc->uri->data.chk.file_length),
1042  dr->offset, dr->depth);
1043  if (prc->size != bs)
1044  {
1045  GNUNET_asprintf (&dc->emsg,
1046  _
1047  ("Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)"),
1048  bs, dr->depth, (unsigned long long) dr->offset,
1049  (unsigned long long) GNUNET_ntohll (dc->uri->data.
1050  chk.file_length),
1051  prc->size);
1052  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", dc->emsg);
1053  while (NULL != dr->parent)
1054  {
1055  dr->state = BRS_ERROR;
1056  dr = dr->parent;
1057  }
1058  dr->state = BRS_ERROR;
1059  goto signal_error;
1060  }
1061 
1063  &prc->query,
1064  dr);
1066  &skey,
1067  &iv);
1068  if (-1 == GNUNET_CRYPTO_symmetric_decrypt (prc->data,
1069  prc->size,
1070  &skey,
1071  &iv,
1072  pt))
1073  {
1074  GNUNET_break (0);
1075  dc->emsg = GNUNET_strdup (_("internal error decrypting content"));
1076  goto signal_error;
1077  }
1078  off =
1080  dr->offset,
1081  dr->depth);
1082  /* save to disk */
1083  if ((GNUNET_YES == prc->do_store) &&
1084  ((NULL != dc->filename) || (is_recursive_download (dc))) &&
1085  ((dr->depth == dc->treedepth) ||
1087  {
1088  fh = GNUNET_DISK_file_open (NULL != dc->filename
1089  ? dc->filename : dc->temp_filename,
1096  if (NULL == fh)
1097  {
1098  GNUNET_asprintf (&dc->emsg,
1099  _("Download failed: could not open file `%s': %s"),
1100  dc->filename, STRERROR (errno));
1101  goto signal_error;
1102  }
1104  "Saving decrypted block to disk at offset %llu\n",
1105  (unsigned long long) off);
1106  if ((off != GNUNET_DISK_file_seek (fh,
1107  off,
1109  {
1110  GNUNET_asprintf (&dc->emsg,
1111  _("Failed to seek to offset %llu in file `%s': %s"),
1112  (unsigned long long) off,
1113  dc->filename,
1114  STRERROR (errno));
1115  goto signal_error;
1116  }
1117  if (prc->size != GNUNET_DISK_file_write (fh, pt, prc->size))
1118  {
1119  GNUNET_asprintf (&dc->emsg,
1120  _("Failed to write block of %u bytes at offset %llu in file `%s': %s"),
1121  (unsigned int) prc->size,
1122  (unsigned long long) off,
1123  dc->filename,
1124  STRERROR (errno));
1125  goto signal_error;
1126  }
1128  fh = NULL;
1129  }
1130 
1131  if (0 == dr->depth)
1132  {
1133  /* DBLOCK, update progress and try recursion if applicable */
1134  app = prc->size;
1135  if (dr->offset < dc->offset)
1136  {
1137  /* starting offset begins in the middle of pt,
1138  * do not count first bytes as progress */
1139  GNUNET_assert (app > (dc->offset - dr->offset));
1140  app -= (dc->offset - dr->offset);
1141  }
1142  if (dr->offset + prc->size > dc->offset + dc->length)
1143  {
1144  /* end of block is after relevant range,
1145  * do not count last bytes as progress */
1146  GNUNET_assert (app >
1147  (dr->offset + prc->size) - (dc->offset + dc->length));
1148  app -= (dr->offset + prc->size) - (dc->offset + dc->length);
1149  }
1150  dc->completed += app;
1151 
1152  /* do recursive download if option is set and either meta data
1153  * says it is a directory or if no meta data is given AND filename
1154  * ends in '.gnd' (top-level case) */
1155  if (is_recursive_download (dc))
1156  GNUNET_FS_directory_list_contents (prc->size, pt, off,
1158  }
1159  GNUNET_assert (dc->completed <= dc->length);
1160  dr->state = BRS_DOWNLOAD_DOWN;
1162  pi.value.download.specifics.progress.data = pt;
1163  pi.value.download.specifics.progress.offset = dr->offset;
1164  pi.value.download.specifics.progress.data_len = prc->size;
1165  pi.value.download.specifics.progress.depth = dr->depth;
1166  pi.value.download.specifics.progress.respect_offered = prc->respect_offered;
1167  pi.value.download.specifics.progress.num_transmissions = prc->num_transmissions;
1169  pi.value.download.specifics.progress.block_download_duration
1171  else
1172  pi.value.download.specifics.progress.block_download_duration
1173  = GNUNET_TIME_UNIT_ZERO; /* found locally */
1175  if (0 == dr->depth)
1176  propagate_up (dr);
1177 
1178  if (dc->completed == dc->length)
1179  {
1180  /* download completed, signal */
1182  "Download completed, truncating file to desired length %llu\n",
1183  (unsigned long long) GNUNET_ntohll (dc->uri->data.
1184  chk.file_length));
1185  /* truncate file to size (since we store IBlocks at the end) */
1186  if (NULL != dc->filename)
1187  {
1188  if (0 !=
1189  TRUNCATE (dc->filename,
1192  dc->filename);
1193  }
1194  GNUNET_assert (0 == dr->depth);
1195  check_completed (dc);
1196  }
1197  if (0 == dr->depth)
1198  {
1199  /* bottom of the tree, no child downloads possible, just sync */
1201  return GNUNET_YES;
1202  }
1203 
1205  "Triggering downloads of children (this block was at depth %u and offset %llu)\n",
1206  dr->depth, (unsigned long long) dr->offset);
1207  GNUNET_assert (0 == (prc->size % sizeof (struct ContentHashKey)));
1208  chkarr = (struct ContentHashKey *) pt;
1209  for (i = dr->num_children - 1; i >= 0; i--)
1210  {
1211  drc = dr->children[i];
1212  switch (drc->state)
1213  {
1214  case BRS_INIT:
1215  if ((drc->chk_idx + 1) * sizeof (struct ContentHashKey) > prc->size)
1216  {
1217  /* 'chkarr' does not have enough space for this chk_idx;
1218  internal error! */
1219  GNUNET_break (0); GNUNET_assert (0);
1220  dc->emsg = GNUNET_strdup (_("internal error decoding tree"));
1221  goto signal_error;
1222  }
1223  drc->chk = chkarr[drc->chk_idx];
1224  drc->state = BRS_CHK_SET;
1225  if (GNUNET_YES == dc->issue_requests)
1226  schedule_block_download (dc, drc);
1227  break;
1228  case BRS_RECONSTRUCT_DOWN:
1229  GNUNET_assert (0);
1230  break;
1232  GNUNET_assert (0);
1233  break;
1234  case BRS_RECONSTRUCT_UP:
1235  GNUNET_assert (0);
1236  break;
1237  case BRS_CHK_SET:
1238  GNUNET_assert (0);
1239  break;
1240  case BRS_DOWNLOAD_DOWN:
1241  GNUNET_assert (0);
1242  break;
1243  case BRS_DOWNLOAD_UP:
1244  GNUNET_assert (0);
1245  break;
1246  case BRS_ERROR:
1247  GNUNET_assert (0);
1248  break;
1249  default:
1250  GNUNET_assert (0);
1251  break;
1252  }
1253  }
1255  return GNUNET_YES;
1256 
1257 signal_error:
1258  if (NULL != fh)
1261  pi.value.download.specifics.error.message = dc->emsg;
1263  GNUNET_MQ_destroy (dc->mq);
1264  dc->mq = NULL;
1266  dc->top_request = NULL;
1268  dc->active = NULL;
1269  if (NULL != dc->job_queue)
1270  {
1272  dc->job_queue = NULL;
1273  }
1275  return GNUNET_NO;
1276 }
struct GNUNET_HashCode query
Hash of data.
Definition: fs_download.c:143
Closure for iterator processing results.
Definition: fs_download.c:137
Create file if it doesn&#39;t exist.
Context for controlling a download.
Definition: fs_api.h:1768
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:215
struct GNUNET_FS_DownloadContext * dc
Our download context.
Definition: fs_download.c:153
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition: fs_api.h:1949
content hash key
Definition: fs.h:53
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition: fs_api.c:1944
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define STRERROR(i)
Definition: plibc.h:676
static void trigger_recursive_download(void *cls, const char *filename, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, size_t length, const void *data)
We found an entry in a directory.
Definition: fs_download.c:851
struct DownloadRequest * top_request
Top-level download request.
Definition: fs_api.h:1882
uint64_t offset
Offset of the corresponding block.
Definition: fs_api.h:1722
#define GNUNET_NO
Definition: gnunet_common.h:81
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk, later to what we want to have).
Definition: fs_api.h:1715
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:241
We&#39;ve calculated the CHK bottom-up based on what we have on disk, which may not be what the desired C...
Definition: fs_api.h:1660
enum BlockRequestState state
State in the FSM.
Definition: fs_api.h:1742
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
char * temp_filename
Where are we writing the data temporarily (name of the file, can be NULL!); used if we do not have a ...
Definition: fs_api.h:1855
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Initial state, block has only been allocated (since it is relevant to the overall download request)...
Definition: fs_api.h:1636
void GNUNET_FS_dequeue_(struct GNUNET_FS_QueueEntry *qe)
Dequeue a job from the queue.
Definition: fs_api.c:363
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
struct GNUNET_TIME_Absolute last_transmission
When did we last transmit the request?
Definition: fs_download.c:158
Do not append temporary data to the target file (for the IBlocks).
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static char * value
Value of the record to add/remove.
unsigned int chk_idx
Offset of the CHK for this block in the parent block.
Definition: fs_api.h:1737
static uint64_t compute_disk_offset(uint64_t fsize, uint64_t off, unsigned int depth)
We&#39;re storing the IBLOCKS after the DBLOCKS on disk (so that we only have to truncate the file once w...
Definition: fs_download.c:69
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:1049
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
int do_store
Flag to indicate if this block should be stored on disk.
Definition: fs_download.c:173
union GNUNET_FS_Uri::@16 data
We&#39;ve checked the block on the path down the tree, and the content on disk did match the desired CHK...
Definition: fs_api.h:1644
static void check_completed(struct GNUNET_FS_DownloadContext *dc)
Check if all child-downloads have completed (or trigger them if necessary) and once we&#39;re completely ...
Definition: fs_download.c:376
const void * data
Data found in P2P network.
Definition: fs_download.c:148
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
int issue_requests
Are we ready to issue requests (reconstructions are finished)?
Definition: fs_api.h:1961
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
static int fh
Handle to the unique file.
We&#39;ve calculated the CHK bottom-up based on the meta data.
Definition: fs_api.h:1652
uint64_t offset
What is the first offset that we&#39;re interested in?
Definition: fs_api.h:1904
We&#39;ve successfully downloaded this block, but the children still need to be either downloaded or veri...
Definition: fs_api.h:1678
void GNUNET_CRYPTO_hash_to_aes_key(const struct GNUNET_HashCode *hc, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
Convert a hashcode into a key.
Definition: crypto_hash.c:212
This block and all of its children have been downloaded successfully (full completion propagates up)...
Definition: fs_api.h:1684
uint32_t respect_offered
how much respect did we offer to get this reply?
Definition: fs_download.c:178
char * emsg
Error message, NULL if we&#39;re doing OK.
Definition: fs_api.h:1836
static unsigned int size
Size of the "table".
Definition: peer.c:67
Notification about progress with this download.
int GNUNET_FS_directory_list_contents(size_t size, const void *data, uint64_t offset, GNUNET_FS_DirectoryEntryProcessor dep, void *dep_cls)
Iterate over all entries in a directory.
Definition: fs_directory.c:179
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
We got a block back that matched the query but did not hash to the key (malicious publisher or hash c...
Definition: fs_api.h:1691
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
uint32_t num_transmissions
how often did we transmit the query?
Definition: fs_download.c:183
void GNUNET_FS_free_download_request_(struct DownloadRequest *dr)
(recursively) free download request structure
Definition: fs_download.c:992
Everybody can read.
static void propagate_up(struct DownloadRequest *dr)
Set the state of the given download request to BRS_DOWNLOAD_UP and propagate it up the tree...
Definition: fs_download.c:634
static int is_recursive_download(struct GNUNET_FS_DownloadContext *dc)
Determine if the given download (options and meta data) should cause use to try to do a recursive dow...
Definition: fs_download.c:37
Seek an absolute position (from the start of the file).
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:99
#define GNUNET_log(kind,...)
#define TRUNCATE(f, l)
Definition: plibc.h:647
Open the file for both reading and writing.
unsigned int treedepth
The depth of the file-tree.
Definition: fs_api.h:1944
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:80
uint64_t completed
How many bytes have we already received within the specified range (DBlocks only).
Definition: fs_api.h:1916
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
size_t size
Number of bytes in data.
Definition: fs_download.c:163
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1673
struct DownloadRequest * parent
Parent in the CHK-tree.
Definition: fs_api.h:1704
Information about an active download request.
Definition: fs_api.h:1698
Handle used to access files (and pipes).
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
static void schedule_block_download(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Schedule the download of the specified block in the tree.
Definition: fs_download.c:782
We&#39;ve determined the real, desired CHK for this block (full tree reconstruction failed), request is now pending.
Definition: fs_api.h:1669
size_t GNUNET_FS_tree_calculate_block_size(uint64_t fsize, uint64_t offset, unsigned int depth)
Compute how many bytes of data should be stored in the specified block.
Definition: fs_tree.c:223
Notification that this download encountered an error.
static struct GNUNET_FS_DownloadContext * dc
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
Argument given to the progress callback with information about what is going on.
struct GNUNET_FS_QueueEntry * job_queue
Our entry in the job queue.
Definition: fs_api.h:1860
Here is the call graph for this function:
Here is the caller graph for this function:

◆ encrypt_existing_match()

static int encrypt_existing_match ( struct GNUNET_FS_DownloadContext dc,
const struct ContentHashKey chk,
struct DownloadRequest dr,
const char *  block,
size_t  len,
int  do_store 
)
static

We've found a matching block without downloading it.

Encrypt it and pass it to our "receive" function as if we had received it from the network.

Parameters
dcdownload in question
chkrequest this relates to
drrequest details
blockplaintext data matching request
lennumber of bytes in block
do_storeshould we still store the block on disk?
Returns
GNUNET_OK on success

Definition at line 217 of file fs_download.c.

References ProcessResultClosure::data, ProcessResultClosure::dc, DownloadRequest::depth, ProcessResultClosure::do_store, enc, filename, GNUNET_FS_DownloadContext::filename, GNUNET_BLOCK_TYPE_FS_DBLOCK, GNUNET_BLOCK_TYPE_FS_IBLOCK, GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_hash_to_aes_key(), GNUNET_CRYPTO_symmetric_encrypt(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_ABS, ContentHashKey::key, ProcessResultClosure::last_transmission, len, meta, DownloadRequest::offset, process_result_with_request(), ContentHashKey::query, ProcessResultClosure::query, ProcessResultClosure::size, trigger_recursive_download(), try_reconnect(), ProcessResultClosure::type, and uri.

Referenced by try_top_down_reconstruction().

221 {
222  struct ProcessResultClosure prc;
223  char enc[len];
226  struct GNUNET_HashCode query;
227 
228  GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv);
229  if (-1 == GNUNET_CRYPTO_symmetric_encrypt (block, len, &sk, &iv, enc))
230  {
231  GNUNET_break (0);
232  return GNUNET_SYSERR;
233  }
234  GNUNET_CRYPTO_hash (enc, len, &query);
235  if (0 != memcmp (&query, &chk->query, sizeof (struct GNUNET_HashCode)))
236  {
237  GNUNET_break_op (0);
238  return GNUNET_SYSERR;
239  }
241  "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n",
242  (unsigned int) len,
243  dc->filename, (unsigned long long) dr->offset);
244  /* already got it! */
245  prc.dc = dc;
246  prc.data = enc;
247  prc.size = len;
248  prc.type =
249  (0 ==
251  prc.query = chk->query;
252  prc.do_store = do_store;
253  prc.last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
254  process_result_with_request (&prc, &chk->key, dr);
255  return GNUNET_OK;
256 }
Closure for iterator processing results.
Definition: fs_download.c:137
static int process_result_with_request(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over entries in the pending requests in the &#39;active&#39; map for the reply that we just got...
Definition: fs_download.c:1013
uint64_t offset
Offset of the corresponding block.
Definition: fs_api.h:1722
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
Inner block in the CHK tree.
A 512-bit hashcode.
void GNUNET_CRYPTO_hash_to_aes_key(const struct GNUNET_HashCode *hc, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
Convert a hashcode into a key.
Definition: crypto_hash.c:212
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
static OpusEncoder * enc
OPUS encoder.
#define GNUNET_log(kind,...)
Data block (leaf) in the CHK tree.
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
static struct GNUNET_FS_DownloadContext * dc
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_reconnect()

static void try_reconnect ( struct GNUNET_FS_DownloadContext dc)
static

We've lost our connection with the FS service.

Re-establish it and re-transmit all of our pending requests.

Parameters
dcdownload context that is having trouble

Definition at line 1400 of file fs_download.c.

References do_reconnect(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MQ_destroy(), GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_STD_BACKOFF, GNUNET_TIME_UNIT_MILLISECONDS, GNUNET_YES, GNUNET_FS_DownloadContext::job_queue, GNUNET_FS_DownloadContext::mq, GNUNET_FS_DownloadContext::reconnect_backoff, GNUNET_TIME_Relative::rel_value_us, and GNUNET_FS_DownloadContext::task.

Referenced by do_reconnect(), download_mq_error_handler(), and encrypt_existing_match().

1401 {
1402  if (NULL != dc->mq)
1403  {
1405  "Moving all requests back to pending list\n");
1406  GNUNET_MQ_destroy (dc->mq);
1407  dc->mq = NULL;
1408  }
1409  if (0 == dc->reconnect_backoff.rel_value_us)
1411  else
1413 
1415  "Will try to reconnect in %s\n",
1417  GNUNET_YES));
1418  GNUNET_break (NULL != dc->job_queue);
1419  dc->task =
1421  &do_reconnect,
1422  dc);
1423 }
static void do_reconnect(void *cls)
Reconnect to the FS service and transmit our queries NOW.
Definition: fs_download.c:1362
uint64_t rel_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:727
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_TIME_Relative reconnect_backoff
How long to wait before we try to reconnect to FS service?
Definition: fs_api.h:1934
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_FS_QueueEntry * job_queue
Our entry in the job queue.
Definition: fs_api.h:1860
Here is the call graph for this function:
Here is the caller graph for this function:

◆ trigger_recursive_download()

static void trigger_recursive_download ( void *  cls,
const char *  filename,
const struct GNUNET_FS_Uri uri,
const struct GNUNET_CONTAINER_MetaData meta,
size_t  length,
const void *  data 
)
static

We found an entry in a directory.

Check if the respective child already exists and if not create the respective child download.

Parameters
clsthe parent download
filenamename of the file in the directory
uriURI of the file (CHK or LOC)
metameta data of the file
lengthnumber of bytes in data
datacontents of the file (or NULL if they were not inlined)

Definition at line 851 of file fs_download.c.

References _, GNUNET_FS_DownloadContext::anonymity, GNUNET_FS_DownloadContext::child_head, DIR_SEPARATOR_STR, GNUNET_FS_DownloadContext::filename, fn, GNUNET_asprintf(), GNUNET_break, GNUNET_CONTAINER_meta_data_get_serialized_size(), GNUNET_DISK_directory_create_for_file(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_free_non_null, GNUNET_FS_DIRECTORY_EXT, GNUNET_FS_download_start(), GNUNET_FS_meta_data_suggest_filename(), GNUNET_FS_meta_data_test_for_directory(), GNUNET_FS_uri_chk_get_file_size(), GNUNET_FS_URI_CHK_PREFIX, GNUNET_FS_uri_test_equal(), GNUNET_FS_uri_to_string(), GNUNET_log, GNUNET_OK, GNUNET_strdup, GNUNET_YES, GNUNET_FS_DownloadContext::h, GNUNET_FS_DownloadContext::next, GNUNET_FS_DownloadContext::options, and GNUNET_FS_DownloadContext::uri.

Referenced by encrypt_existing_match(), full_recursive_download(), and process_result_with_request().

857 {
858  struct GNUNET_FS_DownloadContext *dc = cls;
859  struct GNUNET_FS_DownloadContext *cpos;
860  char *temp_name;
861  char *fn;
862  char *us;
863  char *ext;
864  char *dn;
865  char *pos;
866  char *full_name;
867  char *sfn;
868 
869  if (NULL == uri)
870  return; /* entry for the directory itself */
871  cpos = dc->child_head;
872  while (NULL != cpos)
873  {
874  if ((GNUNET_FS_uri_test_equal (uri, cpos->uri)) ||
875  ((NULL != filename) && (0 == strcmp (cpos->filename, filename))))
876  break;
877  cpos = cpos->next;
878  }
879  if (NULL != cpos)
880  return; /* already exists */
881  fn = NULL;
882  if (NULL == filename)
883  {
885  if (NULL == fn)
886  {
887  us = GNUNET_FS_uri_to_string (uri);
888  fn = GNUNET_strdup (&us[strlen (GNUNET_FS_URI_CHK_PREFIX)]);
889  GNUNET_free (us);
890  }
891  else if ('.' == fn[0])
892  {
893  ext = fn;
894  us = GNUNET_FS_uri_to_string (uri);
895  GNUNET_asprintf (&fn, "%s%s", &us[strlen (GNUNET_FS_URI_CHK_PREFIX)],
896  ext);
897  GNUNET_free (ext);
898  GNUNET_free (us);
899  }
900  /* change '\' to '/' (this should have happened
901  * during insertion, but malicious peers may
902  * not have done this) */
903  while (NULL != (pos = strstr (fn, "\\")))
904  *pos = '/';
905  /* remove '../' everywhere (again, well-behaved
906  * peers don't do this, but don't trust that
907  * we did not get something nasty) */
908  while (NULL != (pos = strstr (fn, "../")))
909  {
910  pos[0] = '_';
911  pos[1] = '_';
912  pos[2] = '_';
913  }
914  filename = fn;
915  }
916  if (NULL == dc->filename)
917  {
918  full_name = NULL;
919  }
920  else
921  {
922  dn = GNUNET_strdup (dc->filename);
923  GNUNET_break ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
924  (NULL !=
925  strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
927  sfn = GNUNET_strdup (filename);
928  while ((strlen (sfn) > 0) && ('/' == filename[strlen (sfn) - 1]))
929  sfn[strlen (sfn) - 1] = '\0';
930  if ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
931  (NULL !=
932  strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
934  dn[strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT)] = '\0';
936  ((strlen (filename) < strlen (GNUNET_FS_DIRECTORY_EXT)) ||
937  (NULL ==
938  strstr (filename + strlen (filename) -
940  {
941  GNUNET_asprintf (&full_name, "%s%s%s%s", dn, DIR_SEPARATOR_STR, sfn,
943  }
944  else
945  {
946  GNUNET_asprintf (&full_name, "%s%s%s", dn, DIR_SEPARATOR_STR, sfn);
947  }
948  GNUNET_free (sfn);
949  GNUNET_free (dn);
950  }
951  if ((NULL != full_name) &&
953  {
955  _
956  ("Failed to create directory for recursive download of `%s'\n"),
957  full_name);
958  GNUNET_free (full_name);
960  return;
961  }
962 
963  temp_name = NULL;
965  "Triggering recursive download of size %llu with %u bytes MD\n",
966  (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri),
967  (unsigned int)
970  uri,
971  meta,
972  full_name,
973  temp_name,
974  0,
976  dc->anonymity,
977  dc->options,
978  NULL,
979  dc);
980  GNUNET_free_non_null (full_name);
981  GNUNET_free_non_null (temp_name);
983 }
ssize_t GNUNET_CONTAINER_meta_data_get_serialized_size(const struct GNUNET_CONTAINER_MetaData *md)
Get the size of the full meta-data in serialized form.
char * GNUNET_FS_meta_data_suggest_filename(const struct GNUNET_CONTAINER_MetaData *md)
Suggest a filename based on given metadata.
Definition: fs_misc.c:38
Context for controlling a download.
Definition: fs_api.h:1768
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition: fs_api.h:1949
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
struct GNUNET_FS_DownloadContext * child_head
Head of list of child downloads.
Definition: fs_api.h:1801
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
int GNUNET_FS_uri_test_equal(const struct GNUNET_FS_Uri *u1, const struct GNUNET_FS_Uri *u2)
Test if two URIs are equal.
Definition: fs_uri.c:1204
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_FS_DownloadContext * GNUNET_FS_download_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, const char *filename, const char *tempname, uint64_t offset, uint64_t length, uint32_t anonymity, enum GNUNET_FS_DownloadOptions options, void *cctx, struct GNUNET_FS_DownloadContext *parent)
Download parts of a file.
Definition: fs_download.c:2126
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
char * GNUNET_FS_uri_to_string(const struct GNUNET_FS_Uri *uri)
Convert a URI to a UTF-8 String.
Definition: fs_uri.c:1988
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_FS_DownloadContext * next
Next download belonging to the same parent.
Definition: fs_api.h:1816
#define GNUNET_FS_DIRECTORY_EXT
static char * fn
Filename of the unique file.
static char * filename
int GNUNET_FS_meta_data_test_for_directory(const struct GNUNET_CONTAINER_MetaData *md)
Does the meta-data claim that this is a directory? Checks if the mime-type is that of a GNUnet direct...
Definition: fs_directory.c:54
uint64_t GNUNET_FS_uri_chk_get_file_size(const struct GNUNET_FS_Uri *uri)
What is the size of the file that this URI refers to?
Definition: fs_uri.c:1359
#define GNUNET_log(kind,...)
#define GNUNET_FS_URI_CHK_PREFIX
Definition: fs_download.c:837
uint32_t anonymity
Desired level of anonymity.
Definition: fs_api.h:1939
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
#define DIR_SEPARATOR_STR
Definition: plibc.h:632
static struct GNUNET_FS_DownloadContext * dc
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ full_recursive_download()

static void full_recursive_download ( struct GNUNET_FS_DownloadContext dc)
static

We're done downloading a directory.

Open the file and trigger all of the (remaining) child downloads.

Parameters
dccontext of download that just completed

Definition at line 297 of file fs_download.c.

References _, ProcessResultClosure::data, GNUNET_FS_DownloadContext::filename, GNUNET_assert, GNUNET_DISK_file_close(), GNUNET_DISK_file_map(), GNUNET_DISK_file_open(), GNUNET_DISK_file_unmap(), GNUNET_DISK_MAP_TYPE_READ, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_FS_directory_list_contents(), GNUNET_FS_uri_chk_get_file_size(), GNUNET_log, GNUNET_log_strerror_file, GNUNET_OK, h, m, ProcessResultClosure::size, GNUNET_FS_DownloadContext::temp_filename, trigger_recursive_download(), UNLINK, and GNUNET_FS_DownloadContext::uri.

Referenced by check_completed().

298 {
299  size_t size;
300  uint64_t size64;
301  void *data;
302  struct GNUNET_DISK_FileHandle *h;
303  struct GNUNET_DISK_MapHandle *m;
304 
305  size64 = GNUNET_FS_uri_chk_get_file_size (dc->uri);
306  size = (size_t) size64;
307  if (size64 != (uint64_t) size)
308  {
310  _("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n"));
311  return;
312  }
313  if (NULL != dc->filename)
314  {
318  }
319  else
320  {
321  GNUNET_assert (NULL != dc->temp_filename);
325  }
326  if (NULL == h)
327  return; /* oops */
328  data = GNUNET_DISK_file_map (h,
329  &m,
331  size);
332  if (NULL == data)
333  {
335  _("Directory too large for system address space\n"));
336  }
337  else
338  {
339  if (GNUNET_OK !=
341  data,
342  0,
344  dc))
345  {
347  _("Failed to access full directroy contents of `%s' for recursive download\n"),
348  dc->filename);
349  }
351  }
353  if (NULL == dc->filename)
354  {
355  if (0 != UNLINK (dc->temp_filename))
357  "unlink",
358  dc->temp_filename);
360  dc->temp_filename = NULL;
361  }
362 }
Open the file for reading.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void * GNUNET_DISK_file_map(const struct GNUNET_DISK_FileHandle *h, struct GNUNET_DISK_MapHandle **m, enum GNUNET_DISK_MapType access, size_t len)
Map a file into memory.
Definition: disk.c:2020
static void trigger_recursive_download(void *cls, const char *filename, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, size_t length, const void *data)
We found an entry in a directory.
Definition: fs_download.c:851
Nobody is allowed to do anything to the file.
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
char * temp_filename
Where are we writing the data temporarily (name of the file, can be NULL!); used if we do not have a ...
Definition: fs_api.h:1855
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
#define UNLINK(f)
Definition: plibc.h:666
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
Read-only memory map.
static unsigned int size
Size of the "table".
Definition: peer.c:67
int GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:2100
int GNUNET_FS_directory_list_contents(size_t size, const void *data, uint64_t offset, GNUNET_FS_DirectoryEntryProcessor dep, void *dep_cls)
Iterate over all entries in a directory.
Definition: fs_directory.c:179
uint64_t GNUNET_FS_uri_chk_get_file_size(const struct GNUNET_FS_Uri *uri)
What is the size of the file that this URI refers to?
Definition: fs_uri.c:1359
#define GNUNET_log(kind,...)
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
uint32_t data
The data value.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1673
Handle used to access files (and pipes).
Handle for a memory-mapping operation.
Definition: disk.c:1985
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_completed()

static void check_completed ( struct GNUNET_FS_DownloadContext dc)
static

Check if all child-downloads have completed (or trigger them if necessary) and once we're completely done, signal completion (and possibly recurse to parent).

This function MUST be called when the download of a file itself is done or when the download of a file is done and then later a direct child download has completed (and hence this download may complete itself).

Parameters
dcdownload to check for completion of children

Definition at line 376 of file fs_download.c.

References GNUNET_FS_DownloadContext::child_head, GNUNET_FS_DownloadContext::completed, GNUNET_FS_DownloadContext::emsg, full_recursive_download(), GNUNET_break, GNUNET_DISK_file_close(), GNUNET_FS_dequeue_(), GNUNET_FS_download_make_status_(), GNUNET_FS_download_sync_(), GNUNET_FS_STATUS_DOWNLOAD_COMPLETED, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_YES, GNUNET_FS_DownloadContext::has_finished, is_recursive_download(), GNUNET_FS_DownloadContext::job_queue, GNUNET_FS_DownloadContext::length, GNUNET_FS_DownloadContext::next, GNUNET_FS_DownloadContext::parent, GNUNET_FS_DownloadContext::rfh, GNUNET_FS_ProgressInfo::status, and GNUNET_FS_DownloadContext::task.

Referenced by GNUNET_FS_download_start_task_(), process_result_with_request(), reconstruct_cb(), and try_match_block().

377 {
378  struct GNUNET_FS_ProgressInfo pi;
379  struct GNUNET_FS_DownloadContext *pos;
380 
381  /* first, check if we need to download children */
382  if (is_recursive_download (dc))
384  /* then, check if children are done already */
385  for (pos = dc->child_head; NULL != pos; pos = pos->next)
386  {
387  if ( (NULL == pos->emsg) &&
388  (pos->completed < pos->length) )
389  return; /* not done yet */
390  if ( (NULL != pos->child_head) &&
391  (pos->has_finished != GNUNET_YES) )
392  return; /* not transitively done yet */
393  }
394  /* All of our children are done, so mark this download done */
395  dc->has_finished = GNUNET_YES;
396  if (NULL != dc->job_queue)
397  {
399  dc->job_queue = NULL;
400  }
401  if (NULL != dc->task)
402  {
404  dc->task = NULL;
405  }
406  if (NULL != dc->rfh)
407  {
409  dc->rfh = NULL;
410  }
412 
413  /* signal completion */
416 
417  /* let parent know */
418  if (NULL != dc->parent)
419  check_completed (dc->parent);
420 }
Context for controlling a download.
Definition: fs_api.h:1768
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
struct GNUNET_FS_DownloadContext * child_head
Head of list of child downloads.
Definition: fs_api.h:1801
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition: fs_api.c:1944
struct GNUNET_FS_DownloadContext * parent
Parent download (used when downloading files in directories).
Definition: fs_api.h:1790
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_FS_dequeue_(struct GNUNET_FS_QueueEntry *qe)
Dequeue a job from the queue.
Definition: fs_api.c:363
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
Notification that this download completed.
struct GNUNET_FS_DownloadContext * next
Next download belonging to the same parent.
Definition: fs_api.h:1816
static void check_completed(struct GNUNET_FS_DownloadContext *dc)
Check if all child-downloads have completed (or trigger them if necessary) and once we&#39;re completely ...
Definition: fs_download.c:376
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
struct GNUNET_DISK_FileHandle * rfh
File handle for reading data from an existing file (to pass to tree encoder).
Definition: fs_api.h:1871
char * emsg
Error message, NULL if we&#39;re doing OK.
Definition: fs_api.h:1836
int has_finished
Flag set upon transitive completion (includes child downloads).
Definition: fs_api.h:1956
static void full_recursive_download(struct GNUNET_FS_DownloadContext *dc)
We&#39;re done downloading a directory.
Definition: fs_download.c:297
static int is_recursive_download(struct GNUNET_FS_DownloadContext *dc)
Determine if the given download (options and meta data) should cause use to try to do a recursive dow...
Definition: fs_download.c:37
#define GNUNET_YES
Definition: gnunet_common.h:80
uint64_t completed
How many bytes have we already received within the specified range (DBlocks only).
Definition: fs_api.h:1916
Argument given to the progress callback with information about what is going on.
struct GNUNET_FS_QueueEntry * job_queue
Our entry in the job queue.
Definition: fs_api.h:1860
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_match_block()

static void try_match_block ( struct GNUNET_FS_DownloadContext dc,
struct DownloadRequest dr,
const char *  data,
size_t  data_len 
)
static

We got a block of plaintext data (from the meta data).

Try it for upward reconstruction of the data. On success, the top-level block will move to state BRS_DOWNLOAD_UP.

Parameters
dccontext for the download
drdownload request to match against
dataplaintext data, starting from the beginning of the file
data_lennumber of bytes in data

Definition at line 434 of file fs_download.c.

References _, BRS_CHK_SET, BRS_DOWNLOAD_UP, BRS_ERROR, BRS_INIT, BRS_RECONSTRUCT_META_UP, check_completed(), DownloadRequest::children, GNUNET_FS_Uri::chk, DownloadRequest::chk, GNUNET_FS_DownloadContext::completed, ProcessResultClosure::data, GNUNET_FS_Uri::data, DBLOCK_SIZE, DownloadRequest::depth, GNUNET_FS_ProgressInfo::download, GNUNET_FS_DownloadContext::emsg, enc, fh, FileIdentifier::file_length, GNUNET_FS_DownloadContext::filename, fn, GNUNET_asprintf(), GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_hash_to_aes_key(), GNUNET_CRYPTO_symmetric_encrypt(), GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_write(), GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_OPEN_TRUNCATE, GNUNET_DISK_PERM_GROUP_READ, GNUNET_DISK_PERM_OTHER_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_FS_download_make_status_(), GNUNET_FS_download_sync_(), GNUNET_FS_STATUS_DOWNLOAD_ERROR, GNUNET_FS_STATUS_DOWNLOAD_PROGRESS, GNUNET_log_strerror_file, GNUNET_MIN, GNUNET_NO, GNUNET_ntohll(), GNUNET_TIME_UNIT_ZERO, GNUNET_YES, ContentHashKey::key, GNUNET_FS_DownloadContext::length, DownloadRequest::num_children, DownloadRequest::offset, GNUNET_FS_DownloadContext::offset, ContentHashKey::query, DownloadRequest::state, GNUNET_FS_ProgressInfo::status, GNUNET_FS_DownloadContext::temp_filename, TRUNCATE, GNUNET_FS_DownloadContext::uri, and GNUNET_FS_ProgressInfo::value.

Referenced by match_full_data().

436 {
437  struct GNUNET_FS_ProgressInfo pi;
438  unsigned int i;
439  char enc[DBLOCK_SIZE];
440  struct ContentHashKey chks[CHK_PER_INODE];
441  struct ContentHashKey in_chk;
444  size_t dlen;
445  struct DownloadRequest *drc;
446  struct GNUNET_DISK_FileHandle *fh;
447  int complete;
448  const char *fn;
449  const char *odata;
450  size_t odata_len;
451 
452  odata = data;
453  odata_len = data_len;
454  if (BRS_DOWNLOAD_UP == dr->state)
455  return;
456  if (dr->depth > 0)
457  {
458  if ( (dc->offset > 0) ||
459  (dc->length < GNUNET_ntohll (dc->uri->data.chk.file_length)) )
460  {
461  /* NOTE: this test is not tight, but should suffice; the issue
462  here is that 'dr->num_children' may inherently only specify a
463  smaller range than what is in the original file;
464  thus, reconstruction of (some) inner blocks will fail.
465  FIXME: we might eventually want to write a tighter test to
466  maximize the circumstances under which we do succeed with
467  IBlock reconstruction. (need good tests though). */
468  return;
469  }
470  complete = GNUNET_YES;
471  for (i = 0; i < dr->num_children; i++)
472  {
473  drc = dr->children[i];
474  try_match_block (dc, drc, data, data_len);
475  if (drc->state != BRS_RECONSTRUCT_META_UP)
476  complete = GNUNET_NO;
477  else
478  chks[i] = drc->chk;
479  }
480  if (GNUNET_YES != complete)
481  return;
482  data = (const char *) chks;
483  dlen = dr->num_children * sizeof (struct ContentHashKey);
484  }
485  else
486  {
487  if (dr->offset > data_len)
488  return; /* oops */
489  dlen = GNUNET_MIN (data_len - dr->offset, DBLOCK_SIZE);
490  }
491  GNUNET_CRYPTO_hash (&data[dr->offset], dlen, &in_chk.key);
492  GNUNET_CRYPTO_hash_to_aes_key (&in_chk.key, &sk, &iv);
494  dlen,
495  &sk,
496  &iv,
497  enc))
498  {
499  GNUNET_break (0);
500  return;
501  }
502  GNUNET_CRYPTO_hash (enc, dlen, &in_chk.query);
503  switch (dr->state)
504  {
505  case BRS_INIT:
506  dr->chk = in_chk;
508  break;
509  case BRS_CHK_SET:
510  if (0 != memcmp (&in_chk,
511  &dr->chk,
512  sizeof (struct ContentHashKey)))
513  {
514  /* other peer provided bogus meta data */
515  GNUNET_break_op (0);
516  break;
517  }
518  /* write block to disk */
519  fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
520  if (NULL != fn)
521  {
522  fh = GNUNET_DISK_file_open (fn,
530  if (NULL == fh)
531  {
533  GNUNET_asprintf (&dc->emsg,
534  _("Failed to open file `%s' for writing"),
535  fn);
537  dr->state = BRS_ERROR;
539  pi.value.download.specifics.error.message = dc->emsg;
541  return;
542  }
543  if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len))
544  {
546  GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"),
547  fn);
549  dr->state = BRS_ERROR;
551  pi.value.download.specifics.error.message = dc->emsg;
553  return;
554  }
556  }
557  /* signal success */
558  dr->state = BRS_DOWNLOAD_UP;
559  dc->completed = dc->length;
562  pi.value.download.specifics.progress.data = data;
563  pi.value.download.specifics.progress.offset = 0;
564  pi.value.download.specifics.progress.data_len = dlen;
565  pi.value.download.specifics.progress.depth = 0;
566  pi.value.download.specifics.progress.respect_offered = 0;
567  pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO;
569  if ((NULL != dc->filename) &&
570  (0 !=
571  TRUNCATE (dc->filename,
574  dc->filename);
575  check_completed (dc);
576  break;
577  default:
578  /* how did we get here? */
579  GNUNET_break (0);
580  break;
581  }
582 }
static void try_match_block(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr, const char *data, size_t data_len)
We got a block of plaintext data (from the meta data).
Definition: fs_download.c:434
Create file if it doesn&#39;t exist.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:215
content hash key
Definition: fs.h:53
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition: fs_api.c:1944
uint64_t offset
Offset of the corresponding block.
Definition: fs_api.h:1722
#define GNUNET_NO
Definition: gnunet_common.h:81
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk, later to what we want to have).
Definition: fs_api.h:1715
enum BlockRequestState state
State in the FSM.
Definition: fs_api.h:1742
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
char * temp_filename
Where are we writing the data temporarily (name of the file, can be NULL!); used if we do not have a ...
Definition: fs_api.h:1855
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Initial state, block has only been allocated (since it is relevant to the overall download request)...
Definition: fs_api.h:1636
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
Truncate file if it exists.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:1049
union GNUNET_FS_Uri::@16 data
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
static void check_completed(struct GNUNET_FS_DownloadContext *dc)
Check if all child-downloads have completed (or trigger them if necessary) and once we&#39;re completely ...
Definition: fs_download.c:376
#define CHK_PER_INODE
Pick a multiple of 2 here to achive 8-byte alignment! We also probably want DBlocks to have (roughly)...
Definition: fs_api.h:43
static int fh
Handle to the unique file.
We&#39;ve calculated the CHK bottom-up based on the meta data.
Definition: fs_api.h:1652
uint64_t offset
What is the first offset that we&#39;re interested in?
Definition: fs_api.h:1904
void GNUNET_CRYPTO_hash_to_aes_key(const struct GNUNET_HashCode *hc, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
Convert a hashcode into a key.
Definition: crypto_hash.c:212
This block and all of its children have been downloaded successfully (full completion propagates up)...
Definition: fs_api.h:1684
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
char * emsg
Error message, NULL if we&#39;re doing OK.
Definition: fs_api.h:1836
Notification about progress with this download.
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
We got a block back that matched the query but did not hash to the key (malicious publisher or hash c...
Definition: fs_api.h:1691
Everybody can read.
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:99
static OpusEncoder * enc
OPUS encoder.
#define TRUNCATE(f, l)
Definition: plibc.h:647
Open the file for both reading and writing.
#define GNUNET_YES
Definition: gnunet_common.h:80
uint64_t completed
How many bytes have we already received within the specified range (DBlocks only).
Definition: fs_api.h:1916
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
uint32_t data
The data value.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1673
Information about an active download request.
Definition: fs_api.h:1698
Handle used to access files (and pipes).
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
We&#39;ve determined the real, desired CHK for this block (full tree reconstruction failed), request is now pending.
Definition: fs_api.h:1669
Notification that this download encountered an error.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
Argument given to the progress callback with information about what is going on.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ match_full_data()

static int match_full_data ( void *  cls,
const char *  plugin_name,
enum EXTRACTOR_MetaType  type,
enum EXTRACTOR_MetaFormat  format,
const char *  data_mime_type,
const char *  data,
size_t  data_len 
)
static

Type of a function that libextractor calls for each meta data item found.

If we find full data meta data, call 'try_match_block' on it.

Parameters
clsour 'struct GNUNET_FS_DownloadContext*'
plugin_namename of the plugin that produced this value; special values can be used (i.e. '<zlib>' for zlib being used in the main libextractor library and yielding meta data).
typelibextractor-type describing the meta data
formatbasic format information about data
data_mime_typemime-type of data (not of the original file); can be NULL (if mime-type is not known)
dataactual meta-data found
data_lennumber of bytes in data
Returns
0 to continue extracting, 1 to abort

Definition at line 604 of file fs_download.c.

References EXTRACTOR_METATYPE_GNUNET_FULL_DATA, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_uri_chk_get_file_size(), GNUNET_log, GNUNET_FS_DownloadContext::top_request, try_match_block(), and GNUNET_FS_DownloadContext::uri.

Referenced by GNUNET_FS_download_start_task_().

607 {
608  struct GNUNET_FS_DownloadContext *dc = cls;
609 
611  return 0;
612  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u bytes of FD!\n",
613  (unsigned int) data_len);
614  if (GNUNET_FS_uri_chk_get_file_size (dc->uri) != data_len)
615  {
616  GNUNET_break_op (0);
617  return 1; /* bogus meta data */
618  }
619  try_match_block (dc,
620  dc->top_request,
621  data,
622  data_len);
623  return 1;
624 }
static void try_match_block(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr, const char *data, size_t data_len)
We got a block of plaintext data (from the meta data).
Definition: fs_download.c:434
Context for controlling a download.
Definition: fs_api.h:1768
struct DownloadRequest * top_request
Top-level download request.
Definition: fs_api.h:1882
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint64_t GNUNET_FS_uri_chk_get_file_size(const struct GNUNET_FS_Uri *uri)
What is the size of the file that this URI refers to?
Definition: fs_uri.c:1359
#define GNUNET_log(kind,...)
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
uint32_t data
The data value.
static struct GNUNET_FS_DownloadContext * dc
Here is the call graph for this function:
Here is the caller graph for this function:

◆ propagate_up()

static void propagate_up ( struct DownloadRequest dr)
static

Set the state of the given download request to BRS_DOWNLOAD_UP and propagate it up the tree.

Parameters
drdownload request that is done

Definition at line 634 of file fs_download.c.

References BRS_DOWNLOAD_UP, DownloadRequest::children, DownloadRequest::num_children, DownloadRequest::parent, and DownloadRequest::state.

Referenced by process_result_with_request(), and try_top_down_reconstruction().

635 {
636  unsigned int i;
637 
638  do
639  {
640  dr->state = BRS_DOWNLOAD_UP;
641  dr = dr->parent;
642  if (NULL == dr)
643  break;
644  for (i = 0; i < dr->num_children; i++)
645  if (dr->children[i]->state != BRS_DOWNLOAD_UP)
646  break;
647  }
648  while (i == dr->num_children);
649 }
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
enum BlockRequestState state
State in the FSM.
Definition: fs_api.h:1742
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
This block and all of its children have been downloaded successfully (full completion propagates up)...
Definition: fs_api.h:1684
struct DownloadRequest * parent
Parent in the CHK-tree.
Definition: fs_api.h:1704
Here is the caller graph for this function:

◆ try_top_down_reconstruction()

static void try_top_down_reconstruction ( struct GNUNET_FS_DownloadContext dc,
struct DownloadRequest dr 
)
static

Try top-down reconstruction.

Before, the given request node must have the state BRS_CHK_SET. Afterwards, more nodes may have that state or advanced to BRS_DOWNLOAD_DOWN or even BRS_DOWNLOAD_UP. It is also possible to get BRS_ERROR on the top level.

Parameters
dcoverall download this block belongs to
drblock to reconstruct

Definition at line 663 of file fs_download.c.

References BRS_CHK_SET, BRS_DOWNLOAD_DOWN, BRS_DOWNLOAD_UP, BRS_ERROR, BRS_INIT, DownloadRequest::children, DownloadRequest::chk, DownloadRequest::chk_idx, compute_disk_offset(), DBLOCK_SIZE, DownloadRequest::depth, encrypt_existing_match(), GNUNET_FS_DownloadContext::filename, GNUNET_assert, GNUNET_CRYPTO_hash(), GNUNET_DISK_file_read(), GNUNET_DISK_file_seek(), GNUNET_DISK_SEEK_SET, GNUNET_ERROR_TYPE_WARNING, GNUNET_FS_tree_calculate_block_size(), GNUNET_FS_tree_compute_tree_size(), GNUNET_FS_uri_chk_get_file_size(), GNUNET_log_strerror_file, GNUNET_NO, GNUNET_OK, GNUNET_YES, ContentHashKey::key, len, DownloadRequest::num_children, DownloadRequest::offset, GNUNET_FS_DownloadContext::old_file_size, DownloadRequest::parent, propagate_up(), GNUNET_FS_DownloadContext::rfh, DownloadRequest::state, GNUNET_FS_DownloadContext::treedepth, and GNUNET_FS_DownloadContext::uri.

Referenced by GNUNET_FS_download_start_task_().

665 {
666  uint64_t off;
667  char block[DBLOCK_SIZE];
668  struct GNUNET_HashCode key;
669  uint64_t total;
670  size_t len;
671  unsigned int i;
672  struct DownloadRequest *drc;
673  uint64_t child_block_size;
674  const struct ContentHashKey *chks;
675  int up_done;
676 
677  GNUNET_assert (NULL != dc->rfh);
679  total = GNUNET_FS_uri_chk_get_file_size (dc->uri);
680  GNUNET_assert (dr->depth < dc->treedepth);
681  len = GNUNET_FS_tree_calculate_block_size (total, dr->offset, dr->depth);
682  GNUNET_assert (len <= DBLOCK_SIZE);
683  off = compute_disk_offset (total, dr->offset, dr->depth);
684  if (dc->old_file_size < off + len)
685  return; /* failure */
686  if (off != GNUNET_DISK_file_seek (dc->rfh, off, GNUNET_DISK_SEEK_SET))
687  {
689  return; /* failure */
690  }
691  if (len != GNUNET_DISK_file_read (dc->rfh, block, len))
692  {
694  return; /* failure */
695  }
696  GNUNET_CRYPTO_hash (block, len, &key);
697  if (0 != memcmp (&key, &dr->chk.key, sizeof (struct GNUNET_HashCode)))
698  return; /* mismatch */
699  if (GNUNET_OK !=
700  encrypt_existing_match (dc, &dr->chk, dr, block, len, GNUNET_NO))
701  {
702  /* hash matches but encrypted block does not, really bad */
703  dr->state = BRS_ERROR;
704  /* propagate up */
705  while (NULL != dr->parent)
706  {
707  dr = dr->parent;
708  dr->state = BRS_ERROR;
709  }
710  return;
711  }
712  /* block matches */
713  dr->state = BRS_DOWNLOAD_DOWN;
714 
715  /* set CHKs for children */
716  up_done = GNUNET_YES;
717  chks = (const struct ContentHashKey *) block;
718  for (i = 0; i < dr->num_children; i++)
719  {
720  drc = dr->children[i];
721  GNUNET_assert (drc->offset >= dr->offset);
722  child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth);
723  GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size);
724  if (BRS_INIT == drc->state)
725  {
726  drc->state = BRS_CHK_SET;
727  drc->chk = chks[drc->chk_idx];
728  try_top_down_reconstruction (dc, drc);
729  }
730  if (BRS_DOWNLOAD_UP != drc->state)
731  up_done = GNUNET_NO; /* children not all done */
732  }
733  if (GNUNET_YES == up_done)
734  propagate_up (dr); /* children all done (or no children...) */
735 }
content hash key
Definition: fs.h:53
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
static void try_top_down_reconstruction(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Try top-down reconstruction.
Definition: fs_download.c:663
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:881
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint64_t offset
Offset of the corresponding block.
Definition: fs_api.h:1722
uint64_t GNUNET_FS_tree_compute_tree_size(unsigned int depth)
Calculate how many bytes of payload a block tree of the given depth MAY correspond to at most (this f...
Definition: fs_tree.c:157
#define GNUNET_NO
Definition: gnunet_common.h:81
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk, later to what we want to have).
Definition: fs_api.h:1715
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:241
enum BlockRequestState state
State in the FSM.
Definition: fs_api.h:1742
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
Initial state, block has only been allocated (since it is relevant to the overall download request)...
Definition: fs_api.h:1636
uint64_t old_file_size
What was the size of the file on disk that we&#39;re downloading before we started? Used to detect if the...
Definition: fs_api.h:1924
unsigned int chk_idx
Offset of the CHK for this block in the parent block.
Definition: fs_api.h:1737
static uint64_t compute_disk_offset(uint64_t fsize, uint64_t off, unsigned int depth)
We&#39;re storing the IBLOCKS after the DBLOCKS on disk (so that we only have to truncate the file once w...
Definition: fs_download.c:69
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
static int encrypt_existing_match(struct GNUNET_FS_DownloadContext *dc, const struct ContentHashKey *chk, struct DownloadRequest *dr, const char *block, size_t len, int do_store)
We&#39;ve found a matching block without downloading it.
Definition: fs_download.c:217
A 512-bit hashcode.
We&#39;ve successfully downloaded this block, but the children still need to be either downloaded or veri...
Definition: fs_api.h:1678
struct GNUNET_DISK_FileHandle * rfh
File handle for reading data from an existing file (to pass to tree encoder).
Definition: fs_api.h:1871
This block and all of its children have been downloaded successfully (full completion propagates up)...
Definition: fs_api.h:1684
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
struct GNUNET_HashCode key
The key used in the DHT.
We got a block back that matched the query but did not hash to the key (malicious publisher or hash c...
Definition: fs_api.h:1691
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
static void propagate_up(struct DownloadRequest *dr)
Set the state of the given download request to BRS_DOWNLOAD_UP and propagate it up the tree...
Definition: fs_download.c:634
Seek an absolute position (from the start of the file).
uint64_t GNUNET_FS_uri_chk_get_file_size(const struct GNUNET_FS_Uri *uri)
What is the size of the file that this URI refers to?
Definition: fs_uri.c:1359
unsigned int treedepth
The depth of the file-tree.
Definition: fs_api.h:1944
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
struct DownloadRequest * parent
Parent in the CHK-tree.
Definition: fs_api.h:1704
Information about an active download request.
Definition: fs_api.h:1698
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
We&#39;ve determined the real, desired CHK for this block (full tree reconstruction failed), request is now pending.
Definition: fs_api.h:1669
size_t GNUNET_FS_tree_calculate_block_size(uint64_t fsize, uint64_t offset, unsigned int depth)
Compute how many bytes of data should be stored in the specified block.
Definition: fs_tree.c:223
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ retry_entry()

static int retry_entry ( void *  cls,
const struct GNUNET_HashCode key,
void *  entry 
)
static

Add entries to the message queue.

Parameters
clsour download context
keyunused
entryentry of type struct DownloadRequest
Returns
GNUNET_OK

Definition at line 747 of file fs_download.c.

References GNUNET_FS_DownloadContext::anonymity, SearchMessage::anonymity_level, DownloadRequest::chk, DownloadRequest::depth, env, GNUNET_BLOCK_TYPE_FS_DBLOCK, GNUNET_BLOCK_TYPE_FS_IBLOCK, GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY, GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY, GNUNET_FS_SEARCH_OPTION_NONE, GNUNET_MESSAGE_TYPE_FS_START_SEARCH, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_OK, GNUNET_FS_DownloadContext::mq, SearchMessage::options, GNUNET_FS_DownloadContext::options, SearchMessage::query, ContentHashKey::query, SearchMessage::target, GNUNET_FS_DownloadContext::target, and SearchMessage::type.

Referenced by do_reconnect(), oprelease_overlay_configure_topology(), overlay_link_completed(), and schedule_block_download().

750 {
751  struct GNUNET_FS_DownloadContext *dc = cls;
752  struct DownloadRequest *dr = entry;
753  struct SearchMessage *sm;
754  struct GNUNET_MQ_Envelope *env;
755 
756  env = GNUNET_MQ_msg (sm,
760  else
762  if (0 == dr->depth)
763  sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK);
764  else
765  sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK);
766  sm->anonymity_level = htonl (dc->anonymity);
767  sm->target = dc->target;
768  sm->query = dr->chk.query;
769  GNUNET_MQ_send (dc->mq,
770  env);
771  return GNUNET_OK;
772 }
No options (use defaults for everything).
Context for controlling a download.
Definition: fs_api.h:1768
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition: fs_api.h:1949
uint32_t options
Bitmask with options.
Definition: fs.h:292
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk, later to what we want to have).
Definition: fs_api.h:1715
struct GNUNET_PeerIdentity target
If the request is for a DBLOCK or IBLOCK, this is the identity of the peer that is known to have a re...
Definition: fs.h:314
struct GNUNET_HashCode query
Hash of the public key for UBLOCKs; Hash of the CHK-encoded block for DBLOCKS and IBLOCKS...
Definition: fs.h:320
Only download from the local host, do not access remote systems (no P2P)
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
Inner block in the CHK tree.
uint32_t type
Type of the content that we&#39;re looking for.
Definition: fs.h:297
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_MESSAGE_TYPE_FS_START_SEARCH
Client asks FS service to start a (keyword) search.
struct GNUNET_PeerIdentity target
Identity of the peer having the content, or all-zeros if we don&#39;t know of such a peer.
Definition: fs_api.h:1888
uint32_t anonymity
Desired level of anonymity.
Definition: fs_api.h:1939
Only search the local host, do not search remote systems (no P2P)
Data block (leaf) in the CHK tree.
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
Message sent from a GNUnet (fs) search activity to the gnunet-service-fs to start a search...
Definition: fs.h:275
Information about an active download request.
Definition: fs_api.h:1698
uint32_t anonymity_level
Desired anonymity level, big-endian.
Definition: fs.h:302
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
static struct GNUNET_FS_DownloadContext * dc
Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_block_download()

static void schedule_block_download ( struct GNUNET_FS_DownloadContext dc,
struct DownloadRequest dr 
)
static

Schedule the download of the specified block in the tree.

Parameters
dcoverall download this block belongs to
drrequest to schedule

Definition at line 782 of file fs_download.c.

References GNUNET_FS_DownloadContext::active, BRS_CHK_SET, BRS_DOWNLOAD_DOWN, BRS_DOWNLOAD_UP, BRS_ERROR, BRS_INIT, BRS_RECONSTRUCT_DOWN, BRS_RECONSTRUCT_META_UP, BRS_RECONSTRUCT_UP, DownloadRequest::children, DownloadRequest::chk, DownloadRequest::depth, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_contains_value(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_FS_DownloadContext::mq, DownloadRequest::num_children, DownloadRequest::offset, ContentHashKey::query, retry_entry(), and DownloadRequest::state.

Referenced by GNUNET_FS_download_start_task_(), process_result_with_request(), and reconstruct_cont().

784 {
785  unsigned int i;
786 
787  switch (dr->state)
788  {
789  case BRS_INIT:
790  GNUNET_assert (0);
791  break;
793  GNUNET_assert (0);
794  break;
796  GNUNET_assert (0);
797  break;
798  case BRS_RECONSTRUCT_UP:
799  GNUNET_assert (0);
800  break;
801  case BRS_CHK_SET:
802  /* normal case, start download */
803  break;
804  case BRS_DOWNLOAD_DOWN:
805  for (i = 0; i < dr->num_children; i++)
806  schedule_block_download (dc, dr->children[i]);
807  return;
808  case BRS_DOWNLOAD_UP:
809  /* We're done! */
810  return;
811  case BRS_ERROR:
812  GNUNET_break (0);
813  return;
814  }
816  "Scheduling download at offset %llu and depth %u for `%s'\n",
817  (unsigned long long) dr->offset,
818  dr->depth,
819  GNUNET_h2s (&dr->chk.query));
820  if (GNUNET_NO !=
822  &dr->chk.query,
823  dr))
824  return; /* already active */
826  &dr->chk.query,
827  dr,
829  if (NULL == dc->mq)
830  return; /* download not active */
831  retry_entry (dc,
832  &dr->chk.query,
833  dr);
834 }
static int retry_entry(void *cls, const struct GNUNET_HashCode *key, void *entry)
Add entries to the message queue.
Definition: fs_download.c:747
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint64_t offset
Offset of the corresponding block.
Definition: fs_api.h:1722
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk, later to what we want to have).
Definition: fs_api.h:1715
We&#39;ve calculated the CHK bottom-up based on what we have on disk, which may not be what the desired C...
Definition: fs_api.h:1660
enum BlockRequestState state
State in the FSM.
Definition: fs_api.h:1742
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Initial state, block has only been allocated (since it is relevant to the overall download request)...
Definition: fs_api.h:1636
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
We&#39;ve checked the block on the path down the tree, and the content on disk did match the desired CHK...
Definition: fs_api.h:1644
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
We&#39;ve calculated the CHK bottom-up based on the meta data.
Definition: fs_api.h:1652
We&#39;ve successfully downloaded this block, but the children still need to be either downloaded or veri...
Definition: fs_api.h:1678
This block and all of its children have been downloaded successfully (full completion propagates up)...
Definition: fs_api.h:1684
int GNUNET_CONTAINER_multihashmap_contains_value(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Check if the map contains the given value under the given key.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
We got a block back that matched the query but did not hash to the key (malicious publisher or hash c...
Definition: fs_api.h:1691
Allow multiple values with the same key.
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
static void schedule_block_download(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Schedule the download of the specified block in the tree.
Definition: fs_download.c:782
We&#39;ve determined the real, desired CHK for this block (full tree reconstruction failed), request is now pending.
Definition: fs_api.h:1669
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_FS_free_download_request_()

void GNUNET_FS_free_download_request_ ( struct DownloadRequest dr)

(recursively) free download request structure

Parameters
drrequest to free

Definition at line 992 of file fs_download.c.

References DownloadRequest::children, GNUNET_free, GNUNET_free_non_null, and DownloadRequest::num_children.

Referenced by free_download_context(), GNUNET_FS_download_signal_suspend_(), GNUNET_FS_download_stop(), process_result_with_request(), and read_download_request().

993 {
994  if (NULL == dr)
995  return;
996  for (unsigned int i = 0; i < dr->num_children; i++)
999  GNUNET_free (dr);
1000 }
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
void GNUNET_FS_free_download_request_(struct DownloadRequest *dr)
(recursively) free download request structure
Definition: fs_download.c:992
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ check_put()

static int check_put ( void *  cls,
const struct ClientPutMessage cm 
)
static

Type of a function to call when we check the PUT message from the service.

Parameters
clsclosure
msgmessage received

Definition at line 1287 of file fs_download.c.

References GNUNET_OK.

1289 {
1290  /* any varsize length is OK */
1291  return GNUNET_OK;
1292 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78

◆ handle_put()

static void handle_put ( void *  cls,
const struct ClientPutMessage cm 
)
static

Type of a function to call when we receive a message from the service.

Parameters
clsclosure
msgmessage received

Definition at line 1303 of file fs_download.c.

References GNUNET_FS_DownloadContext::active, ProcessResultClosure::data, ProcessResultClosure::dc, ProcessResultClosure::do_store, GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_TIME_absolute_ntoh(), GNUNET_YES, ClientPutMessage::header, ProcessResultClosure::last_transmission, ClientPutMessage::last_transmission, ProcessResultClosure::num_transmissions, ClientPutMessage::num_transmissions, process_result_with_request(), ProcessResultClosure::query, ProcessResultClosure::respect_offered, ClientPutMessage::respect_offered, ProcessResultClosure::size, GNUNET_MessageHeader::size, ProcessResultClosure::type, and ClientPutMessage::type.

1305 {
1306  struct GNUNET_FS_DownloadContext *dc = cls;
1307  uint16_t msize = ntohs (cm->header.size) - sizeof (*cm);
1308  struct ProcessResultClosure prc;
1309 
1310  prc.dc = dc;
1311  prc.data = &cm[1];
1313  prc.size = msize;
1314  prc.type = ntohl (cm->type);
1315  prc.do_store = GNUNET_YES;
1316  prc.respect_offered = ntohl (cm->respect_offered);
1317  prc.num_transmissions = ntohl (cm->num_transmissions);
1318  GNUNET_CRYPTO_hash (prc.data,
1319  msize,
1320  &prc.query);
1322  "Received result for query `%s' from FS service\n",
1323  GNUNET_h2s (&prc.query));
1325  &prc.query,
1327  &prc);
1328 }
Closure for iterator processing results.
Definition: fs_download.c:137
Context for controlling a download.
Definition: fs_api.h:1768
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
struct GNUNET_FS_DownloadContext * dc
Our download context.
Definition: fs_download.c:153
static int process_result_with_request(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over entries in the pending requests in the &#39;active&#39; map for the reply that we just got...
Definition: fs_download.c:1013
struct GNUNET_MessageHeader header
Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
Definition: fs.h:370
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_TIME_AbsoluteNBO last_transmission
When was the last time we&#39;ve tried to download this block? (FOREVER if unknown/not relevant) ...
Definition: fs.h:386
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
uint32_t respect_offered
How much respect did we offer (in total) before getting an answer (estimate).
Definition: fs.h:398
uint32_t type
Type of the block (in big endian).
Definition: fs.h:375
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct GNUNET_FS_DownloadContext * dc
uint32_t num_transmissions
How often did we transmit this query before getting an answer (estimate).
Definition: fs.h:392
Here is the call graph for this function:

◆ download_mq_error_handler()

static void download_mq_error_handler ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue.

Not every message queue implementation supports an error handler.

Parameters
clsclosure with the struct GNUNET_FS_DownloadContext *
errorerror code

Definition at line 1340 of file fs_download.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MQ_destroy(), GNUNET_FS_DownloadContext::mq, and try_reconnect().

Referenced by do_reconnect().

1342 {
1343  struct GNUNET_FS_DownloadContext *dc = cls;
1344 
1345  if (NULL != dc->mq)
1346  {
1347  GNUNET_MQ_destroy (dc->mq);
1348  dc->mq = NULL;
1349  }
1351  "Transmitting download request failed, trying to reconnect\n");
1352  try_reconnect (dc);
1353 }
Context for controlling a download.
Definition: fs_api.h:1768
static void try_reconnect(struct GNUNET_FS_DownloadContext *dc)
We&#39;ve lost our connection with the FS service.
Definition: fs_download.c:1400
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
static struct GNUNET_FS_DownloadContext * dc
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_reconnect()

static void do_reconnect ( void *  cls)
static

Reconnect to the FS service and transmit our queries NOW.

Parameters
clsour download context

Definition at line 1362 of file fs_download.c.

References GNUNET_FS_DownloadContext::active, GNUNET_FS_Handle::cfg, download_mq_error_handler(), GNUNET_CLIENT_connect(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_MESSAGE_TYPE_FS_PUT, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_FS_DownloadContext::h, GNUNET_FS_DownloadContext::mq, retry_entry(), GNUNET_FS_DownloadContext::task, and try_reconnect().

Referenced by activate_fs_download(), and try_reconnect().

1363 {
1364  struct GNUNET_FS_DownloadContext *dc = cls;
1365  struct GNUNET_MQ_MessageHandler handlers[] = {
1366  GNUNET_MQ_hd_var_size (put,
1368  struct ClientPutMessage,
1369  dc),
1371  };
1372 
1373  dc->task = NULL;
1374  dc->mq = GNUNET_CLIENT_connect (dc->h->cfg,
1375  "fs",
1376  handlers,
1378  dc);
1379  if (NULL == dc->mq)
1380  {
1382  "Connecting to `%s'-service failed, will try again.\n", "FS");
1383  try_reconnect (dc);
1384  return;
1385  }
1387  &retry_entry,
1388  dc);
1389 }
static int retry_entry(void *cls, const struct GNUNET_HashCode *key, void *entry)
Add entries to the message queue.
Definition: fs_download.c:747
Context for controlling a download.
Definition: fs_api.h:1768
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:901
static void download_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
Definition: fs_download.c:1340
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static void try_reconnect(struct GNUNET_FS_DownloadContext *dc)
We&#39;ve lost our connection with the FS service.
Definition: fs_download.c:1400
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
Message handler for a specific message type.
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
Response from FS service with a result for a previous FS search.
Definition: fs.h:364
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_MESSAGE_TYPE_FS_PUT
P2P response with content or active migration of content.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static struct GNUNET_FS_DownloadContext * dc
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: fs_api.h:1092
Here is the call graph for this function:
Here is the caller graph for this function:

◆ activate_fs_download()

static void activate_fs_download ( void *  cls)
static

We're allowed to ask the FS service for our blocks.

Start the download.

Parameters
clsthe 'struct GNUNET_FS_DownloadContext'
mqhandle to use for communcation with FS (we must destroy it!)

Definition at line 1433 of file fs_download.c.

References GNUNET_FS_DownloadContext::active, do_reconnect(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_download_make_status_(), GNUNET_FS_STATUS_DOWNLOAD_ACTIVE, GNUNET_log, GNUNET_FS_DownloadContext::mq, and GNUNET_FS_ProgressInfo::status.

Referenced by GNUNET_FS_download_resume(), and GNUNET_FS_download_start_downloading_().

1434 {
1435  struct GNUNET_FS_DownloadContext *dc = cls;
1436  struct GNUNET_FS_ProgressInfo pi;
1437 
1438  GNUNET_assert (NULL == dc->mq);
1439  GNUNET_assert (NULL != dc->active);
1440  do_reconnect (dc);
1441  if (NULL != dc->mq)
1443  "Download activated\n");
1446  dc);
1447 }
static void do_reconnect(void *cls)
Reconnect to the FS service and transmit our queries NOW.
Definition: fs_download.c:1362
Context for controlling a download.
Definition: fs_api.h:1768
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
Notification that this download is now actively being pursued (as opposed to waiting in the queue)...
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
static struct GNUNET_FS_DownloadContext * dc
Argument given to the progress callback with information about what is going on.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ deactivate_fs_download()

static void deactivate_fs_download ( void *  cls)
static

We must stop to ask the FS service for our blocks.

Pause the download.

Parameters
clsthe struct GNUNET_FS_DownloadContext

Definition at line 1456 of file fs_download.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_download_make_status_(), GNUNET_FS_STATUS_DOWNLOAD_INACTIVE, GNUNET_log, GNUNET_MQ_destroy(), GNUNET_FS_DownloadContext::mq, and GNUNET_FS_ProgressInfo::status.

Referenced by GNUNET_FS_download_resume(), GNUNET_FS_download_start_downloading_(), and GNUNET_FS_download_suspend().

1457 {
1458  struct GNUNET_FS_DownloadContext *dc = cls;
1459  struct GNUNET_FS_ProgressInfo pi;
1460 
1462  "Download deactivated\n");
1463  if (NULL != dc->mq)
1464  {
1465  GNUNET_MQ_destroy (dc->mq);
1466  dc->mq = NULL;
1467  }
1470  dc);
1471 }
Context for controlling a download.
Definition: fs_api.h:1768
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
Notification that this download is no longer actively being pursued (back in the queue).
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
static struct GNUNET_FS_DownloadContext * dc
Argument given to the progress callback with information about what is going on.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_download_request()

static struct DownloadRequest* create_download_request ( struct DownloadRequest parent,
unsigned int  chk_idx,
unsigned int  depth,
uint64_t  dr_offset,
uint64_t  file_start_offset,
uint64_t  desired_length 
)
static

(recursively) Create a download request structure.

Parameters
parentparent of the current entry
chk_idxindex of the chk for this block in the parent block
depthdepth of the current entry, 0 are the DBLOCKs, top level block is 'dc->treedepth - 1'
dr_offsetoffset in the original file this block maps to (as in, offset of the first byte of the first DBLOCK in the subtree rooted in the returned download request tree)
file_start_offsetdesired starting offset for the download in the original file; requesting tree should not contain DBLOCKs prior to the file_start_offset
desired_lengthdesired number of bytes the user wanted to access (from file_start_offset). Resulting tree should not contain DBLOCKs after file_start_offset + file_length.
Returns
download request tree for the given range of DBLOCKs at the specified depth

Definition at line 1494 of file fs_download.c.

References DownloadRequest::children, DownloadRequest::chk_idx, CHK_PER_INODE, DownloadRequest::depth, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_tree_compute_tree_size(), GNUNET_log, GNUNET_new, GNUNET_new_array, DownloadRequest::num_children, DownloadRequest::offset, and DownloadRequest::parent.

Referenced by GNUNET_FS_download_start_task_().

1500 {
1501  struct DownloadRequest *dr;
1502  unsigned int i;
1503  unsigned int head_skip;
1504  uint64_t child_block_size;
1505 
1506  dr = GNUNET_new (struct DownloadRequest);
1507  dr->parent = parent;
1508  dr->depth = depth;
1509  dr->offset = dr_offset;
1510  dr->chk_idx = chk_idx;
1511  if (0 == depth)
1512  return dr;
1513  child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1);
1514 
1515  /* calculate how many blocks at this level are not interesting
1516  * from the start (rounded down), either because of the requested
1517  * file offset or because this IBlock is further along */
1518  if (dr_offset < file_start_offset)
1519  {
1520  head_skip = (file_start_offset - dr_offset) / child_block_size;
1521  }
1522  else
1523  {
1524  head_skip = 0;
1525  }
1526 
1527  /* calculate index of last block at this level that is interesting (rounded up) */
1528  dr->num_children = (file_start_offset + desired_length - dr_offset) / child_block_size;
1529  if (dr->num_children * child_block_size <
1530  file_start_offset + desired_length - dr_offset)
1531  dr->num_children++; /* round up */
1532  GNUNET_assert (dr->num_children > head_skip);
1533  dr->num_children -= head_skip;
1534  if (dr->num_children > CHK_PER_INODE)
1535  dr->num_children = CHK_PER_INODE; /* cap at max */
1537  "Block at offset %llu and depth %u has %u children\n",
1538  (unsigned long long) dr_offset,
1539  depth,
1540  dr->num_children);
1541 
1542  /* now we can get the total number of *interesting* children for this block */
1543 
1544  /* why else would we have gotten here to begin with? (that'd be a bad logic error) */
1545  GNUNET_assert (dr->num_children > 0);
1546 
1547  dr->children =
1549  struct DownloadRequest *);
1550  for (i = 0; i < dr->num_children; i++)
1551  {
1552  dr->children[i] =
1554  i + head_skip,
1555  depth - 1,
1556  dr_offset + (i + head_skip) * child_block_size,
1557  file_start_offset,
1558  desired_length);
1559  }
1560  return dr;
1561 }
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
static struct DownloadRequest * create_download_request(struct DownloadRequest *parent, unsigned int chk_idx, unsigned int depth, uint64_t dr_offset, uint64_t file_start_offset, uint64_t desired_length)
(recursively) Create a download request structure.
Definition: fs_download.c:1494
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint64_t offset
Offset of the corresponding block.
Definition: fs_api.h:1722
uint64_t GNUNET_FS_tree_compute_tree_size(unsigned int depth)
Calculate how many bytes of payload a block tree of the given depth MAY correspond to at most (this f...
Definition: fs_tree.c:157
#define GNUNET_new(type)
Allocate a struct or union of the given type.
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
unsigned int chk_idx
Offset of the CHK for this block in the parent block.
Definition: fs_api.h:1737
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define CHK_PER_INODE
Pick a multiple of 2 here to achive 8-byte alignment! We also probably want DBlocks to have (roughly)...
Definition: fs_api.h:43
#define GNUNET_log(kind,...)
struct DownloadRequest * parent
Parent in the CHK-tree.
Definition: fs_api.h:1704
Information about an active download request.
Definition: fs_api.h:1698
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconstruct_cont()

static void reconstruct_cont ( void *  cls)
static

Continuation after a possible attempt to reconstruct the current IBlock from the existing file.

Parameters
clsthe 'struct ReconstructContext'

Definition at line 1571 of file fs_download.c.

References GNUNET_break, GNUNET_DISK_file_close(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_YES, GNUNET_FS_DownloadContext::issue_requests, GNUNET_FS_DownloadContext::rfh, schedule_block_download(), GNUNET_FS_DownloadContext::task, and GNUNET_FS_DownloadContext::top_request.

Referenced by GNUNET_FS_download_start_task_().

1572 {
1573  struct GNUNET_FS_DownloadContext *dc = cls;
1574 
1575  /* clean up state from tree encoder */
1576  if (NULL != dc->task)
1577  {
1579  dc->task = NULL;
1580  }
1581  if (NULL != dc->rfh)
1582  {
1584  dc->rfh = NULL;
1585  }
1586  /* start "normal" download */
1587  dc->issue_requests = GNUNET_YES;
1589  "Starting normal download\n");
1591 }
Context for controlling a download.
Definition: fs_api.h:1768
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
struct DownloadRequest * top_request
Top-level download request.
Definition: fs_api.h:1882
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int issue_requests
Are we ready to issue requests (reconstructions are finished)?
Definition: fs_api.h:1961
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
struct GNUNET_DISK_FileHandle * rfh
File handle for reading data from an existing file (to pass to tree encoder).
Definition: fs_api.h:1871
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
static void schedule_block_download(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Schedule the download of the specified block in the tree.
Definition: fs_download.c:782
static struct GNUNET_FS_DownloadContext * dc
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_next_block()

static void get_next_block ( void *  cls)
static

Task requesting the next block from the tree encoder.

Parameters
clsthe 'struct GNUJNET_FS_DownloadContext' we're processing

Definition at line 1600 of file fs_download.c.

References GNUNET_FS_tree_encoder_next(), GNUNET_FS_DownloadContext::task, and GNUNET_FS_DownloadContext::te.

Referenced by GNUNET_FS_download_start_task_(), and reconstruct_cb().

1601 {
1602  struct GNUNET_FS_DownloadContext *dc = cls;
1603 
1604  dc->task = NULL;
1606 }
Context for controlling a download.
Definition: fs_api.h:1768
void GNUNET_FS_tree_encoder_next(struct GNUNET_FS_TreeEncoder *te)
Encrypt the next block of the file (and call proc and progress accordingly; or of course "cont" if we...
Definition: fs_tree.c:332
struct GNUNET_FS_TreeEncoder * te
Tree encoder used for the reconstruction.
Definition: fs_api.h:1865
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
static struct GNUNET_FS_DownloadContext * dc
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconstruct_cb()

static void reconstruct_cb ( void *  cls,
const struct ContentHashKey chk,
uint64_t  offset,
unsigned int  depth,
enum GNUNET_BLOCK_Type  type,
const void *  block,
uint16_t  block_size 
)
static

Function called asking for the current (encoded) block to be processed.

After processing the client should either call "GNUNET_FS_tree_encode_next" or (on error) "GNUNET_FS_tree_encode_finish".

This function checks if the content on disk matches the expected content based on the URI.

Parameters
clsclosure
chkcontent hash key for the block
offsetoffset of the block
depthdepth of the block, 0 for DBLOCK
typetype of the block (IBLOCK or DBLOCK)
blockthe (encrypted) block
block_sizesize of block (in bytes)

Definition at line 1627 of file fs_download.c.

References GNUNET_FS_DownloadContext::active, BRS_CHK_SET, BRS_DOWNLOAD_DOWN, BRS_DOWNLOAD_UP, BRS_ERROR, BRS_INIT, BRS_RECONSTRUCT_DOWN, BRS_RECONSTRUCT_META_UP, BRS_RECONSTRUCT_UP, check_completed(), DownloadRequest::children, GNUNET_FS_Uri::chk, DownloadRequest::chk, DownloadRequest::chk_idx, GNUNET_FS_DownloadContext::completed, GNUNET_FS_Uri::data, DownloadRequest::depth, GNUNET_FS_ProgressInfo::download, FileIdentifier::file_length, GNUNET_FS_DownloadContext::filename, get_next_block(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_FS_download_make_status_(), GNUNET_FS_STATUS_DOWNLOAD_PROGRESS, GNUNET_FS_tree_compute_tree_size(), GNUNET_log, GNUNET_log_strerror_file, GNUNET_MIN, GNUNET_ntohll(), GNUNET_SCHEDULER_add_now(), GNUNET_TIME_UNIT_ZERO, GNUNET_FS_DownloadContext::length, DownloadRequest::num_children, DownloadRequest::offset, GNUNET_FS_DownloadContext::offset, ContentHashKey::query, DownloadRequest::state, GNUNET_FS_ProgressInfo::status, GNUNET_FS_DownloadContext::task, GNUNET_FS_DownloadContext::top_request, TRUNCATE, GNUNET_FS_DownloadContext::uri, and GNUNET_FS_ProgressInfo::value.

Referenced by GNUNET_FS_download_start_task_().

1634 {
1635  struct GNUNET_FS_DownloadContext *dc = cls;
1636  struct GNUNET_FS_ProgressInfo pi;
1637  struct DownloadRequest *dr;
1638  uint64_t blen;
1639  unsigned int chld;
1640 
1641  /* find corresponding request entry */
1642  dr = dc->top_request;
1643  while (dr->depth > depth)
1644  {
1645  GNUNET_assert (dr->num_children > 0);
1646  blen = GNUNET_FS_tree_compute_tree_size (dr->depth - 1);
1647  chld = (offset - dr->offset) / blen;
1648  if (chld < dr->children[0]->chk_idx)
1649  {
1651  "Block %u < %u irrelevant for our range\n",
1652  chld,
1653  dr->children[0]->chk_idx);
1655  dc);
1656  return; /* irrelevant block */
1657  }
1658  if (chld > dr->children[dr->num_children-1]->chk_idx)
1659  {
1661  "Block %u > %u irrelevant for our range\n",
1662  chld,
1663  dr->children[dr->num_children-1]->chk_idx);
1665  return; /* irrelevant block */
1666  }
1667  dr = dr->children[chld - dr->children[0]->chk_idx];
1668  }
1670  "Matched TE block with request at offset %llu and depth %u in state %d\n",
1671  (unsigned long long) dr->offset,
1672  dr->depth,
1673  dr->state);
1674  /* FIXME: this code needs more testing and might
1675  need to handle more states... */
1676  switch (dr->state)
1677  {
1678  case BRS_INIT:
1679  break;
1680  case BRS_RECONSTRUCT_DOWN:
1681  break;
1683  break;
1684  case BRS_RECONSTRUCT_UP:
1685  break;
1686  case BRS_CHK_SET:
1687  if (0 == memcmp (chk, &dr->chk, sizeof (struct ContentHashKey)))
1688  {
1690  "Reconstruction succeeded, can use block at offset %llu, depth %u\n",
1691  (unsigned long long) offset,
1692  depth);
1693  /* block matches, hence tree below matches;
1694  * this request is done! */
1695  dr->state = BRS_DOWNLOAD_UP;
1697  &dr->chk.query,
1698  dr);
1699  /* calculate how many bytes of payload this block
1700  * corresponds to */
1702  /* how many of those bytes are in the requested range? */
1703  blen = GNUNET_MIN (blen, dc->length + dc->offset - dr->offset);
1704  /* signal progress */
1705  dc->completed += blen;
1707  pi.value.download.specifics.progress.data = NULL;
1708  pi.value.download.specifics.progress.offset = offset;
1709  pi.value.download.specifics.progress.data_len = 0;
1710  pi.value.download.specifics.progress.depth = 0;
1711  pi.value.download.specifics.progress.respect_offered = 0;
1712  pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO;
1714  /* FIXME: duplicated code from 'process_result_with_request - refactor */
1715  if (dc->completed == dc->length)
1716  {
1717  /* download completed, signal */
1719  "Download completed, truncating file to desired length %llu\n",
1720  (unsigned long long) GNUNET_ntohll (dc->uri->data.
1721  chk.file_length));
1722  /* truncate file to size (since we store IBlocks at the end) */
1723  if (NULL != dc->filename)
1724  {
1725  if (0 !=
1726  TRUNCATE (dc->filename,
1729  dc->filename);
1730  }
1731  }
1732  }
1733  else
1735  "Reconstruction failed, need to download block at offset %llu, depth %u\n",
1736  (unsigned long long) offset,
1737  depth);
1738  break;
1739  case BRS_DOWNLOAD_DOWN:
1740  break;
1741  case BRS_DOWNLOAD_UP:
1742  break;
1743  case BRS_ERROR:
1744  break;
1745  default:
1746  GNUNET_assert (0);
1747  break;
1748  }
1750  dc);
1751  if ( (dr == dc->top_request) &&
1752  (dr->state == BRS_DOWNLOAD_UP) )
1753  check_completed (dc);
1754 }
Context for controlling a download.
Definition: fs_api.h:1768
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:215
content hash key
Definition: fs.h:53
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition: fs_api.h:1709
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct DownloadRequest * top_request
Top-level download request.
Definition: fs_api.h:1882
uint64_t offset
Offset of the corresponding block.
Definition: fs_api.h:1722
uint64_t GNUNET_FS_tree_compute_tree_size(unsigned int depth)
Calculate how many bytes of payload a block tree of the given depth MAY correspond to at most (this f...
Definition: fs_tree.c:157
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk, later to what we want to have).
Definition: fs_api.h:1715
We&#39;ve calculated the CHK bottom-up based on what we have on disk, which may not be what the desired C...
Definition: fs_api.h:1660
enum BlockRequestState state
State in the FSM.
Definition: fs_api.h:1742
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
unsigned int num_children
Number of entries in children array.
Definition: fs_api.h:1727
Initial state, block has only been allocated (since it is relevant to the overall download request)...
Definition: fs_api.h:1636
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
unsigned int chk_idx
Offset of the CHK for this block in the parent block.
Definition: fs_api.h:1737
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
union GNUNET_FS_Uri::@16 data
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
We&#39;ve checked the block on the path down the tree, and the content on disk did match the desired CHK...
Definition: fs_api.h:1644
static void check_completed(struct GNUNET_FS_DownloadContext *dc)
Check if all child-downloads have completed (or trigger them if necessary) and once we&#39;re completely ...
Definition: fs_download.c:376
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
We&#39;ve calculated the CHK bottom-up based on the meta data.
Definition: fs_api.h:1652
uint64_t offset
What is the first offset that we&#39;re interested in?
Definition: fs_api.h:1904
We&#39;ve successfully downloaded this block, but the children still need to be either downloaded or veri...
Definition: fs_api.h:1678
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
This block and all of its children have been downloaded successfully (full completion propagates up)...
Definition: fs_api.h:1684
Notification about progress with this download.
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
We got a block back that matched the query but did not hash to the key (malicious publisher or hash c...
Definition: fs_api.h:1691
static void get_next_block(void *cls)
Task requesting the next block from the tree encoder.
Definition: fs_download.c:1600
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:99
#define GNUNET_log(kind,...)
#define TRUNCATE(f, l)
Definition: plibc.h:647
uint64_t completed
How many bytes have we already received within the specified range (DBlocks only).
Definition: fs_api.h:1916
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
Information about an active download request.
Definition: fs_api.h:1698
unsigned int depth
Depth of the corresponding block in the tree.
Definition: fs_api.h:1732
We&#39;ve determined the real, desired CHK for this block (full tree reconstruction failed), request is now pending.
Definition: fs_api.h:1669
static struct GNUNET_FS_DownloadContext * dc
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
Argument given to the progress callback with information about what is going on.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fh_reader()

static size_t fh_reader ( void *  cls,
uint64_t  offset,
size_t  max,
void *  buf,
char **  emsg 
)
static

Function called by the tree encoder to obtain a block of plaintext data (for the lowest level of the tree).

Parameters
clsour 'struct ReconstructContext'
offsetidentifies which block to get
max(maximum) number of bytes to get; returning fewer will also cause errors
bufwhere to copy the plaintext buffer
emsglocation to store an error message (on error)
Returns
number of bytes copied to buf, 0 on error

Definition at line 1770 of file fs_download.c.

References fh, GNUNET_DISK_file_read(), GNUNET_DISK_file_seek(), GNUNET_DISK_SEEK_SET, GNUNET_strdup, ret, and GNUNET_FS_DownloadContext::rfh.

Referenced by GNUNET_FS_download_start_task_().

1771 {
1772  struct GNUNET_FS_DownloadContext *dc = cls;
1773  struct GNUNET_DISK_FileHandle *fh = dc->rfh;
1774  ssize_t ret;
1775 
1776  if (NULL != emsg)
1777  *emsg = NULL;
1778  if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET))
1779  {
1780  if (NULL != emsg)
1781  *emsg = GNUNET_strdup (strerror (errno));
1782  return 0;
1783  }
1784  ret = GNUNET_DISK_file_read (fh, buf, max);
1785  if (ret < 0)
1786  {
1787  if (NULL != emsg)
1788  *emsg = GNUNET_strdup (strerror (errno));
1789  return 0;
1790  }
1791  return ret;
1792 }
Context for controlling a download.
Definition: fs_api.h:1768
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:881
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:241
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static char buf[2048]
static int fh
Handle to the unique file.
struct GNUNET_DISK_FileHandle * rfh
File handle for reading data from an existing file (to pass to tree encoder).
Definition: fs_api.h:1871
Seek an absolute position (from the start of the file).
Handle used to access files (and pipes).
static struct GNUNET_FS_DownloadContext * dc
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_FS_download_start_task_()

void GNUNET_FS_download_start_task_ ( void *  cls)

Task that creates the initial (top-level) download request for the file.

Parameters
clsthe 'struct GNUNET_FS_DownloadContext'

Definition at line 1802 of file fs_download.c.

References _, BRS_CHK_SET, BRS_DOWNLOAD_DOWN, BRS_DOWNLOAD_UP, BRS_ERROR, check_completed(), GNUNET_FS_Uri::chk, FileIdentifier::chk, DownloadRequest::chk, create_download_request(), GNUNET_FS_Uri::data, GNUNET_FS_ProgressInfo::download, GNUNET_FS_DownloadContext::emsg, fh, fh_reader(), Location::fi, GNUNET_FS_DownloadContext::filename, get_next_block(), GNUNET_asprintf(), GNUNET_assert, GNUNET_CONTAINER_meta_data_get_serialized_size(), GNUNET_CONTAINER_meta_data_iterate(), GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_test(), GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_OPEN_READ, GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_OPEN_TRUNCATE, GNUNET_DISK_PERM_GROUP_READ, GNUNET_DISK_PERM_NONE, GNUNET_DISK_PERM_OTHER_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_download_make_status_(), GNUNET_FS_download_start_downloading_(), GNUNET_FS_download_sync_(), GNUNET_FS_search_result_sync_(), GNUNET_FS_STATUS_DOWNLOAD_ERROR, GNUNET_FS_STATUS_DOWNLOAD_START, GNUNET_FS_tree_encoder_create(), GNUNET_FS_URI_CHK, GNUNET_FS_uri_chk_get_file_size(), GNUNET_log, GNUNET_SCHEDULER_add_now(), GNUNET_YES, GNUNET_FS_DownloadContext::h, GNUNET_FS_DownloadContext::issue_requests, GNUNET_FS_DownloadContext::length, GNUNET_FS_Uri::loc, match_full_data(), MAX_INLINE_SIZE, GNUNET_FS_DownloadContext::meta, GNUNET_FS_DownloadContext::offset, reconstruct_cb(), reconstruct_cont(), GNUNET_FS_DownloadContext::rfh, schedule_block_download(), GNUNET_FS_DownloadContext::search, DownloadRequest::state, GNUNET_FS_ProgressInfo::status, GNUNET_FS_DownloadContext::task, GNUNET_FS_DownloadContext::te, GNUNET_FS_DownloadContext::top_request, GNUNET_FS_DownloadContext::treedepth, try_top_down_reconstruction(), GNUNET_FS_Uri::type, GNUNET_FS_DownloadContext::uri, and GNUNET_FS_ProgressInfo::value.

Referenced by create_download_context(), and deserialize_download().

1803 {
1804  struct GNUNET_FS_DownloadContext *dc = cls;
1805  struct GNUNET_FS_ProgressInfo pi;
1806  struct GNUNET_DISK_FileHandle *fh;
1807 
1809  "Start task running...\n");
1810  dc->task = NULL;
1811  if (0 == dc->length)
1812  {
1813  /* no bytes required! */
1814  if (NULL != dc->filename)
1815  {
1816  fh = GNUNET_DISK_file_open (dc->filename,
1819  ((0 ==
1827  }
1830  pi.value.download.specifics.start.meta = dc->meta;
1832  check_completed (dc);
1833  return;
1834  }
1835  if (NULL != dc->emsg)
1836  return;
1837  if (NULL == dc->top_request)
1838  {
1839  dc->top_request =
1840  create_download_request (NULL, 0, dc->treedepth - 1, 0, dc->offset,
1841  dc->length);
1842  dc->top_request->state = BRS_CHK_SET;
1843  dc->top_request->chk =
1844  (dc->uri->type ==
1845  GNUNET_FS_URI_CHK) ? dc->uri->data.chk.chk : dc->uri->data.loc.fi.chk;
1846  /* signal start */
1848  if (NULL != dc->search)
1851  pi.value.download.specifics.start.meta = dc->meta;
1853  }
1855  /* attempt reconstruction from disk */
1857  dc->rfh =
1860  if (dc->top_request->state == BRS_CHK_SET)
1861  {
1862  if (NULL != dc->rfh)
1863  {
1864  /* first, try top-down */
1866  "Trying top-down reconstruction for `%s'\n", dc->filename);
1868  switch (dc->top_request->state)
1869  {
1870  case BRS_CHK_SET:
1871  break; /* normal */
1872  case BRS_DOWNLOAD_DOWN:
1873  break; /* normal, some blocks already down */
1874  case BRS_DOWNLOAD_UP:
1875  /* already done entirely, party! */
1876  if (NULL != dc->rfh)
1877  {
1878  /* avoid hanging on to file handle longer than
1879  * necessary */
1881  dc->rfh = NULL;
1882  }
1883  return;
1884  case BRS_ERROR:
1885  GNUNET_asprintf (&dc->emsg, _("Invalid URI"));
1888  pi.value.download.specifics.error.message = dc->emsg;
1890  return;
1891  default:
1892  GNUNET_assert (0);
1893  break;
1894  }
1895  }
1896  }
1897  /* attempt reconstruction from meta data */
1899  (NULL != dc->meta))
1900  {
1902  "Trying to find embedded meta data for download of size %llu with %u bytes MD\n",
1903  (unsigned long long) GNUNET_FS_uri_chk_get_file_size (dc->uri),
1904  (unsigned int)
1907  if (BRS_DOWNLOAD_UP == dc->top_request->state)
1908  {
1909  if (NULL != dc->rfh)
1910  {
1911  /* avoid hanging on to file handle longer than
1912  * necessary */
1914  dc->rfh = NULL;
1915  }
1916  return; /* finished, status update was already done for us */
1917  }
1918  }
1919  if (NULL != dc->rfh)
1920  {
1921  /* finally, actually run bottom-up */
1923  "Trying bottom-up reconstruction of file `%s'\n", dc->filename);
1924  dc->te =
1927  dc,
1928  &fh_reader,
1929  &reconstruct_cb,
1930  NULL,
1931  &reconstruct_cont);
1933  dc);
1934  }
1935  else
1936  {
1937  /* simple, top-level download */
1938  dc->issue_requests = GNUNET_YES;
1940  }
1941  if (BRS_DOWNLOAD_UP == dc->top_request->state)
1942  check_completed (dc);
1943 }
ssize_t GNUNET_CONTAINER_meta_data_get_serialized_size(const struct GNUNET_CONTAINER_MetaData *md)
Get the size of the full meta-data in serialized form.
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:669
Notification that we have started this download.
Open the file for reading.
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:104
Create file if it doesn&#39;t exist.
Context for controlling a download.
Definition: fs_api.h:1768
static void reconstruct_cb(void *cls, const struct ContentHashKey *chk, uint64_t offset, unsigned int depth, enum GNUNET_BLOCK_Type type, const void *block, uint16_t block_size)
Function called asking for the current (encoded) block to be processed.
Definition: fs_download.c:1627
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:215
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
static void try_top_down_reconstruction(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Try top-down reconstruction.
Definition: fs_download.c:663
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition: fs_api.c:1944
static struct DownloadRequest * create_download_request(struct DownloadRequest *parent, unsigned int chk_idx, unsigned int depth, uint64_t dr_offset, uint64_t file_start_offset, uint64_t desired_length)
(recursively) Create a download request structure.
Definition: fs_download.c:1494
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct DownloadRequest * top_request
Top-level download request.
Definition: fs_api.h:1882
Nobody is allowed to do anything to the file.
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk, later to what we want to have).
Definition: fs_api.h:1715
enum BlockRequestState state
State in the FSM.
Definition: fs_api.h:1742
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#define MAX_INLINE_SIZE
Maximum size for a file to be considered for inlining in a directory.
Definition: fs_api.h:49
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
Truncate file if it exists.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
union GNUNET_FS_Uri::@16 data
void GNUNET_FS_search_result_sync_(struct GNUNET_FS_SearchResult *sr)
Synchronize this search result with its mirror on disk.
Definition: fs_api.c:2048
static void check_completed(struct GNUNET_FS_DownloadContext *dc)
Check if all child-downloads have completed (or trigger them if necessary) and once we&#39;re completely ...
Definition: fs_download.c:376
static void reconstruct_cont(void *cls)
Continuation after a possible attempt to reconstruct the current IBlock from the existing file...
Definition: fs_download.c:1571
int issue_requests
Are we ready to issue requests (reconstructions are finished)?
Definition: fs_api.h:1961
static int fh
Handle to the unique file.
struct GNUNET_FS_TreeEncoder * te
Tree encoder used for the reconstruction.
Definition: fs_api.h:1865
struct GNUNET_FS_TreeEncoder * GNUNET_FS_tree_encoder_create(struct GNUNET_FS_Handle *h, uint64_t size, void *cls, GNUNET_FS_DataReader reader, GNUNET_FS_TreeBlockProcessor proc, GNUNET_FS_TreeProgressCallback progress, GNUNET_SCHEDULER_TaskCallback cont)
Initialize a tree encoder.
Definition: fs_tree.c:270
uint64_t offset
What is the first offset that we&#39;re interested in?
Definition: fs_api.h:1904
static size_t fh_reader(void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
Function called by the tree encoder to obtain a block of plaintext data (for the lowest level of the ...
Definition: fs_download.c:1770
We&#39;ve successfully downloaded this block, but the children still need to be either downloaded or veri...
Definition: fs_api.h:1678
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
struct GNUNET_DISK_FileHandle * rfh
File handle for reading data from an existing file (to pass to tree encoder).
Definition: fs_api.h:1871
This block and all of its children have been downloaded successfully (full completion propagates up)...
Definition: fs_api.h:1684
Content-hash-key (simple file).
Definition: fs_api.h:146
struct GNUNET_FS_SearchResult * search
Associated search (used when downloading files based on search results), or NULL for none...
Definition: fs_api.h:1796
char * emsg
Error message, NULL if we&#39;re doing OK.
Definition: fs_api.h:1836
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
We got a block back that matched the query but did not hash to the key (malicious publisher or hash c...
Definition: fs_api.h:1691
static void get_next_block(void *cls)
Task requesting the next block from the tree encoder.
Definition: fs_download.c:1600
Everybody can read.
static int match_full_data(void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len)
Type of a function that libextractor calls for each meta data item found.
Definition: fs_download.c:604
uint64_t GNUNET_FS_uri_chk_get_file_size(const struct GNUNET_FS_Uri *uri)
What is the size of the file that this URI refers to?
Definition: fs_uri.c:1359
struct FileIdentifier fi
Information about the shared file.
Definition: fs_api.h:118
int GNUNET_CONTAINER_meta_data_iterate(const struct GNUNET_CONTAINER_MetaData *md, EXTRACTOR_MetaDataProcessor iter, void *iter_cls)
Iterate over MD entries.
#define GNUNET_log(kind,...)
Open the file for both reading and writing.
unsigned int treedepth
The depth of the file-tree.
Definition: fs_api.h:1944
struct GNUNET_CONTAINER_MetaData * meta
Known meta-data for the file (can be NULL).
Definition: fs_api.h:1831
struct Location loc
Information needed to retrieve a file including signed location (identity of a peer) of the content...
Definition: fs_api.h:221
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1673
void GNUNET_FS_download_start_downloading_(struct GNUNET_FS_DownloadContext *dc)
Start the downloading process (by entering the queue).
Definition: fs_download.c:2244
Handle used to access files (and pipes).
static void schedule_block_download(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Schedule the download of the specified block in the tree.
Definition: fs_download.c:782
We&#39;ve determined the real, desired CHK for this block (full tree reconstruction failed), request is now pending.
Definition: fs_api.h:1669
Notification that this download encountered an error.
static struct GNUNET_FS_DownloadContext * dc
Argument given to the progress callback with information about what is going on.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_FS_download_signal_suspend_()

void GNUNET_FS_download_signal_suspend_ ( void *  cls)

Create SUSPEND event for the given download operation and then clean up our state (without stop signal).

Parameters
clsthe 'struct GNUNET_FS_DownloadContext' to signal for

Definition at line 1953 of file fs_download.c.

References GNUNET_FS_DownloadContext::active, GNUNET_FS_DownloadContext::child_head, GNUNET_FS_DownloadContext::child_tail, GNUNET_FS_SearchResult::download, GNUNET_FS_DownloadContext::filename, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_meta_data_destroy(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_DISK_file_close(), GNUNET_free, GNUNET_free_non_null, GNUNET_FS_dequeue_(), GNUNET_FS_download_make_status_(), GNUNET_FS_end_top(), GNUNET_FS_free_download_request_(), GNUNET_FS_STATUS_DOWNLOAD_SUSPEND, GNUNET_FS_tree_encoder_finish(), GNUNET_FS_uri_destroy(), GNUNET_SCHEDULER_cancel(), GNUNET_FS_DownloadContext::h, GNUNET_FS_DownloadContext::job_queue, GNUNET_FS_DownloadContext::meta, GNUNET_FS_DownloadContext::parent, GNUNET_FS_DownloadContext::rfh, GNUNET_FS_DownloadContext::search, GNUNET_FS_DownloadContext::serialization, GNUNET_FS_ProgressInfo::status, GNUNET_FS_DownloadContext::task, GNUNET_FS_DownloadContext::te, GNUNET_FS_DownloadContext::temp_filename, GNUNET_FS_DownloadContext::top, GNUNET_FS_DownloadContext::top_request, and GNUNET_FS_DownloadContext::uri.

Referenced by deserialize_download(), GNUNET_FS_download_start(), search_result_stop(), and search_result_suspend().

1954 {
1955  struct GNUNET_FS_DownloadContext *dc = cls;
1956  struct GNUNET_FS_ProgressInfo pi;
1957 
1958  if (NULL != dc->top)
1959  GNUNET_FS_end_top (dc->h, dc->top);
1960  while (NULL != dc->child_head)
1962  if (NULL != dc->search)
1963  {
1964  dc->search->download = NULL;
1965  dc->search = NULL;
1966  }
1967  if (NULL != dc->job_queue)
1968  {
1970  dc->job_queue = NULL;
1971  }
1972  if (NULL != dc->parent)
1974  dc);
1975  if (NULL != dc->task)
1976  {
1978  dc->task = NULL;
1979  }
1982  if (NULL != dc->te)
1983  {
1984  GNUNET_FS_tree_encoder_finish (dc->te, NULL);
1985  dc->te = NULL;
1986  }
1987  if (NULL != dc->rfh)
1988  {
1990  dc->rfh = NULL;
1991  }
1993  if (NULL != dc->active)
1994  {
1996  dc->active = NULL;
1997  }
2000  GNUNET_FS_uri_destroy (dc->uri);
2003  GNUNET_assert (NULL == dc->job_queue);
2004  GNUNET_free (dc);
2005 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Context for controlling a download.
Definition: fs_api.h:1768
struct GNUNET_FS_DownloadContext * download
ID of an associated download based on this search result (or NULL for none).
Definition: fs_api.h:560
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
Notification that this download was suspended.
void GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_DownloadContext *dc)
Fill in all of the generic fields for a download event and call the callback.
Definition: fs_download.c:106
struct GNUNET_FS_DownloadContext * child_head
Head of list of child downloads.
Definition: fs_api.h:1801
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct DownloadRequest * top_request
Top-level download request.
Definition: fs_api.h:1882
struct GNUNET_FS_DownloadContext * parent
Parent download (used when downloading files in directories).
Definition: fs_api.h:1790
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
char * temp_filename
Where are we writing the data temporarily (name of the file, can be NULL!); used if we do not have a ...
Definition: fs_api.h:1855
void GNUNET_FS_dequeue_(struct GNUNET_FS_QueueEntry *qe)
Dequeue a job from the queue.
Definition: fs_api.c:363
char * serialization
Random portion of filename we use for syncing state of this download.
Definition: fs_api.h:1842
void GNUNET_FS_end_top(struct GNUNET_FS_Handle *h, struct TopLevelActivity *top)
Destroy a top-level activity entry.
Definition: fs_api.c:416
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_CONTAINER_meta_data_destroy(struct GNUNET_CONTAINER_MetaData *md)
Free meta data.
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
struct GNUNET_FS_TreeEncoder * te
Tree encoder used for the reconstruction.
Definition: fs_api.h:1865
struct TopLevelActivity * top
Our top-level activity entry (if we are top-level, otherwise NULL).
Definition: fs_api.h:1779
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:670
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
struct GNUNET_DISK_FileHandle * rfh
File handle for reading data from an existing file (to pass to tree encoder).
Definition: fs_api.h:1871
struct GNUNET_FS_SearchResult * search
Associated search (used when downloading files based on search results), or NULL for none...
Definition: fs_api.h:1796
void GNUNET_FS_free_download_request_(struct DownloadRequest *dr)
(recursively) free download request structure
Definition: fs_download.c:992
struct GNUNET_FS_DownloadContext * child_tail
Tail of list of child downloads.
Definition: fs_api.h:1806
struct GNUNET_CONTAINER_MetaData * meta
Known meta-data for the file (can be NULL).
Definition: fs_api.h:1831
void GNUNET_FS_download_signal_suspend_(void *cls)
Create SUSPEND event for the given download operation and then clean up our state (without stop signa...
Definition: fs_download.c:1953
void GNUNET_FS_tree_encoder_finish(struct GNUNET_FS_TreeEncoder *te, char **emsg)
Clean up a tree encoder and return information about possible errors.
Definition: fs_tree.c:444
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
static struct GNUNET_FS_DownloadContext * dc
#define GNUNET_free(ptr)
Wrapper around free.
Argument given to the progress callback with information about what is going on.
struct GNUNET_FS_QueueEntry * job_queue
Our entry in the job queue.
Definition: fs_api.h:1860
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_download_context()

struct GNUNET_FS_DownloadContext* create_download_context ( struct GNUNET_FS_Handle h,
const struct GNUNET_FS_Uri uri,
const struct GNUNET_CONTAINER_MetaData meta,
const char *  filename,
const char *  tempname,
uint64_t  offset,
uint64_t  length,
uint32_t  anonymity,
enum GNUNET_FS_DownloadOptions  options,
void *  cctx 
)

Helper function to setup the download context.

Parameters
hhandle to the file sharing subsystem
urithe URI of the file (determines what to download); CHK or LOC URI
metaknown metadata for the file (can be NULL)
filenamewhere to store the file, maybe NULL (then no file is created on disk and data must be grabbed from the callbacks)
tempnamewhere to store temporary file data, not used if filename is non-NULL; can be NULL (in which case we will pick a name if needed); the temporary file may already exist, in which case we will try to use the data that is there and if it is not what is desired, will overwrite it
offsetat what offset should we start the download (typically 0)
lengthhow many bytes should be downloaded starting at offset
anonymityanonymity level to use for the download
optionsvarious options
cctxinitial value for the client context for this download
Returns
context that can be used to control this download

Definition at line 2028 of file fs_download.c.

References GNUNET_FS_DownloadContext::active, anonymity, GNUNET_FS_DownloadContext::anonymity, GNUNET_FS_DownloadContext::client_info, DBLOCK_SIZE, ProcessResultClosure::dc, GNUNET_FS_DownloadContext::filename, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_meta_data_duplicate(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_DISK_file_size(), GNUNET_DISK_file_test(), GNUNET_DISK_mktemp(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_compute_depth(), GNUNET_FS_download_start_task_(), GNUNET_FS_uri_chk_get_file_size(), GNUNET_FS_uri_dup(), GNUNET_FS_uri_loc_get_peer_identity(), GNUNET_FS_uri_test_chk(), GNUNET_FS_uri_test_loc(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_TIME_absolute_get(), GNUNET_YES, h, GNUNET_FS_DownloadContext::h, is_recursive_download(), GNUNET_FS_DownloadContext::job_queue, GNUNET_FS_DownloadContext::length, GNUNET_FS_DownloadContext::meta, GNUNET_FS_DownloadContext::offset, GNUNET_FS_DownloadContext::old_file_size, options, GNUNET_FS_DownloadContext::options, GNUNET_FS_DownloadContext::start_time, GNUNET_FS_DownloadContext::target, GNUNET_FS_DownloadContext::task, GNUNET_FS_DownloadContext::temp_filename, GNUNET_FS_DownloadContext::treedepth, and GNUNET_FS_DownloadContext::uri.

Referenced by GNUNET_FS_download_start(), and GNUNET_FS_download_start_from_search().

2038 {
2039  struct GNUNET_FS_DownloadContext *dc;
2040 
2042  if ((offset + length < offset) ||
2044  {
2045  GNUNET_break (0);
2046  return NULL;
2047  }
2048  dc = GNUNET_new (struct GNUNET_FS_DownloadContext);
2050  "Starting download %p, %u bytes at offset %llu\n",
2051  dc,
2052  (unsigned int) length,
2053  (unsigned long long) offset);
2054  dc->h = h;
2055  dc->uri = GNUNET_FS_uri_dup (uri);
2057  dc->client_info = cctx;
2059  if (NULL != filename)
2060  {
2064  }
2065  if (GNUNET_FS_uri_test_loc (dc->uri))
2068  dc->offset = offset;
2069  dc->length = length;
2070  dc->anonymity = anonymity;
2071  dc->options = options;
2072  dc->active =
2074  dc->treedepth =
2076  if ((NULL == filename) && (is_recursive_download (dc)))
2077  {
2078  if (NULL != tempname)
2079  dc->temp_filename = GNUNET_strdup (tempname);
2080  else
2081  dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp");
2082  }
2084  "Starting download `%s' of %llu bytes with tree depth %u\n",
2085  filename,
2086  (unsigned long long) length,
2087  dc->treedepth);
2088  GNUNET_assert (NULL == dc->job_queue);
2090  dc);
2091  return dc;
2092 }
int GNUNET_FS_uri_loc_get_peer_identity(const struct GNUNET_FS_Uri *uri, struct GNUNET_PeerIdentity *peer)
Obtain the identity of the peer offering the data.
Definition: fs_uri.c:810
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:669
Context for controlling a download.
Definition: fs_api.h:1768
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition: fs_api.h:1949
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition: fs_api.h:1848
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
char * temp_filename
Where are we writing the data temporarily (name of the file, can be NULL!); used if we do not have a ...
Definition: fs_api.h:1855
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_FS_Uri * GNUNET_FS_uri_dup(const struct GNUNET_FS_Uri *uri)
Duplicate URI.
Definition: fs_uri.c:988
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void * client_info
Context kept for the client.
Definition: fs_api.h:1821
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
uint64_t old_file_size
What was the size of the file on disk that we&#39;re downloading before we started? Used to detect if the...
Definition: fs_api.h:1924
int GNUNET_FS_uri_test_loc(const struct GNUNET_FS_Uri *uri)
Is this a location URI?
Definition: fs_uri.c:1381
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
unsigned int GNUNET_FS_compute_depth(uint64_t flen)
Compute the depth of the CHK tree.
Definition: fs_tree.c:126
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:593
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static char * filename
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
uint64_t offset
What is the first offset that we&#39;re interested in?
Definition: fs_api.h:1904
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
int GNUNET_FS_uri_test_chk(const struct GNUNET_FS_Uri *uri)
Is this a file (or directory) URI?
Definition: fs_uri.c:1345
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
int GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:289
static int is_recursive_download(struct GNUNET_FS_DownloadContext *dc)
Determine if the given download (options and meta data) should cause use to try to do a recursive dow...
Definition: fs_download.c:37
uint64_t GNUNET_FS_uri_chk_get_file_size(const struct GNUNET_FS_Uri *uri)
What is the size of the file that this URI refers to?
Definition: fs_uri.c:1359
struct GNUNET_PeerIdentity target
Identity of the peer having the content, or all-zeros if we don&#39;t know of such a peer.
Definition: fs_api.h:1888
#define GNUNET_log(kind,...)
uint32_t anonymity
Desired level of anonymity.
Definition: fs_api.h:1939
unsigned int treedepth
The depth of the file-tree.
Definition: fs_api.h:1944
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_MetaData * meta
Known meta-data for the file (can be NULL).
Definition: fs_api.h:1831
#define GNUNET_YES
Definition: gnunet_common.h:80
static unsigned int anonymity
struct GNUNET_TIME_Absolute start_time
Time download was started.
Definition: fs_api.h:1929
void GNUNET_FS_download_start_task_(void *cls)
Task that creates the initial (top-level) download request for the file.
Definition: fs_download.c:1802
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition: fs_api.h:1826
static struct GNUNET_FS_DownloadContext * dc
struct GNUNET_FS_QueueEntry * job_queue
Our entry in the job queue.
Definition: fs_api.h:1860
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_duplicate(const struct GNUNET_CONTAINER_MetaData *md)
Duplicate a MetaData token.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_FS_download_start_downloading_()

void GNUNET_FS_download_start_downloading_ ( struct GNUNET_FS_DownloadContext dc)

Start the downloading process (by entering the queue).

Parameters
dcour download context

Definition at line 2244 of file fs_download.c.

References activate_fs_download(), GNUNET_FS_DownloadContext::active, GNUNET_FS_DownloadContext::completed, DBLOCK_SIZE, deactivate_fs_download(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_DOWNLOAD_IS_PROBE, GNUNET_FS_queue_(), GNUNET_FS_QUEUE_PRIORITY_NORMAL, GNUNET_FS_QUEUE_PRIORITY_PROBE, GNUNET_log, GNUNET_FS_DownloadContext::h, GNUNET_FS_DownloadContext::job_queue, GNUNET_FS_DownloadContext::length, GNUNET_FS_DownloadContext::mq, GNUNET_FS_DownloadContext::options, and GNUNET_FS_DownloadContext::task.

Referenced by GNUNET_FS_download_start_task_().

2245 {
2246  if (dc->completed == dc->length)
2247  return;
2248  if (NULL != dc->mq)
2249  return; /* already running */
2250  GNUNET_assert (NULL == dc->job_queue);
2251  GNUNET_assert (NULL == dc->task);
2252  GNUNET_assert (NULL != dc->active);
2253  dc->job_queue
2254  = GNUNET_FS_queue_ (dc->h,
2257  dc,
2258  (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE,
2259  (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
2263  "Download %p put into queue as job %p\n",
2264  dc,
2265  dc->job_queue);
2266 }
This is a probe (low priority).
Definition: fs_api.h:420
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition: fs_api.h:1949
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void activate_fs_download(void *cls)
We&#39;re allowed to ask the FS service for our blocks.
Definition: fs_download.c:1433
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file! ...
Definition: fs_api.h:1910
Internal option used to flag this download as a &#39;probe&#39; for a search result.
struct GNUNET_FS_QueueEntry * GNUNET_FS_queue_(struct GNUNET_FS_Handle *h, GNUNET_SCHEDULER_TaskCallback start, GNUNET_SCHEDULER_TaskCallback stop, void *cls, unsigned int blocks, enum GNUNET_FS_QueuePriority priority)
Add a job to the queue.
Definition: fs_api.c:328
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition: fs_api.h:1877
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the download is being stopped ...
Definition: fs_api.h:1898
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
static void deactivate_fs_download(void *cls)
We must stop to ask the FS service for our blocks.
Definition: fs_download.c:1456
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
uint64_t completed
How many bytes have we already received within the specified range (DBlocks only).
Definition: fs_api.h:1916
Default priority.
Definition: fs_api.h:425
struct GNUNET_FS_QueueEntry * job_queue
Our entry in the job queue.
Definition: fs_api.h:1860
Here is the call graph for this function:
Here is the caller graph for this function: