GNUnet 0.28.0-dev.2
 
Loading...
Searching...
No Matches
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.
 
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).
 
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.
 
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.
 
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.
 
static void try_reconnect (struct GNUNET_FS_DownloadContext *dc)
 We've lost our connection with the FS service.
 
static void trigger_recursive_download (void *cls, const char *filename, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_MetaData *meta, size_t length, const void *data)
 We found an entry in a directory.
 
static void full_recursive_download (struct GNUNET_FS_DownloadContext *dc)
 We're done downloading a directory.
 
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).
 
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).
 
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.
 
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.
 
static void try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
 Try top-down reconstruction.
 
static int retry_entry (void *cls, const struct GNUNET_HashCode *key, void *entry)
 Add entries to the message queue.
 
static void schedule_block_download (struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
 Schedule the download of the specified block in the tree.
 
void GNUNET_FS_free_download_request_ (struct DownloadRequest *dr)
 (recursively) free download request structure
 
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.
 
static void handle_put (void *cls, const struct ClientPutMessage *cm)
 Type of a function to call when we receive a message from the service.
 
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.
 
static void do_reconnect (void *cls)
 Reconnect to the FS service and transmit our queries NOW.
 
static void activate_fs_download (void *cls)
 We're allowed to ask the FS service for our blocks.
 
static void deactivate_fs_download (void *cls)
 We must stop to ask the FS service for our blocks.
 
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.
 
static void reconstruct_cont (void *cls)
 Continuation after a possible attempt to reconstruct the current IBlock from the existing file.
 
static void get_next_block (void *cls)
 Task requesting the next block from the tree encoder.
 
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.
 
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).
 
void GNUNET_FS_download_start_task_ (void *cls)
 Task that creates the initial (top-level) download request for the file.
 
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).
 
static struct GNUNET_FS_DownloadContextcreate_download_context (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_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.
 
struct GNUNET_FS_DownloadContextGNUNET_FS_download_start (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_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.
 
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.
 
void GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc)
 Start the downloading process (by entering the queue).
 
void GNUNET_FS_download_suspend (struct GNUNET_FS_DownloadContext *dc)
 Suspend a download.
 
void GNUNET_FS_download_resume (struct GNUNET_FS_DownloadContext *dc)
 Resume a suspended download.
 
void GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete)
 Stop a download (aborts if download is incomplete).
 

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 848 of file fs_download.c.

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 38 of file fs_download.c.

39{
42 ((NULL == dc->meta) &&
43 ((NULL == dc->filename) ||
44 ((strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
45 (NULL != strstr (dc->filename + strlen (dc->filename)
46 - strlen (GNUNET_FS_DIRECTORY_EXT),
48}
static struct GNUNET_FS_DownloadContext * dc
int GNUNET_FS_meta_data_test_for_directory(const struct GNUNET_FS_MetaData *md)
Does the meta-data claim that this is a directory? Checks if the mime-type is that of a GNUnet direct...
#define GNUNET_FS_DIRECTORY_EXT
@ GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE
Do a recursive download (that is, automatically trigger the download of files in directories).
@ GNUNET_YES
char * filename
Where are we writing the data (name of the file, can be NULL!).
Definition fs_api.h:1835
struct GNUNET_FS_MetaData * meta
Known meta-data for the file (can be NULL).
Definition fs_api.h:1818
enum GNUNET_FS_DownloadOptions options
Options for the download.
Definition fs_api.h:1936

References dc, 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().

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 68 of file fs_download.c.

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

References CHK_PER_INODE, DBLOCK_SIZE, and GNUNET_assert.

Referenced by process_result_with_request(), and try_top_down_reconstruction().

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 104 of file fs_download.c.

106{
107 pi->value.download.dc = dc;
108 pi->value.download.cctx = dc->client_info;
109 pi->value.download.pctx =
110 (NULL == dc->parent) ? NULL : dc->parent->client_info;
111 pi->value.download.sctx =
112 (NULL == dc->search) ? NULL : dc->search->client_info;
113 pi->value.download.uri = dc->uri;
114 pi->value.download.filename = dc->filename;
115 pi->value.download.size = dc->length;
116 /* FIXME: Fix duration calculation to account for pauses */
117 pi->value.download.duration =
119 pi->value.download.completed = dc->completed;
120 pi->value.download.anonymity = dc->anonymity;
121 pi->value.download.eta =
123 pi->value.download.is_active = (NULL == dc->mq) ? GNUNET_NO : GNUNET_YES;
124 pi->fsh = dc->h;
126 dc->client_info = dc->h->upcb (dc->h->upcb_cls, pi);
127 else
129}
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:281
struct GNUNET_REGEX_Search * search
@ GNUNET_FS_DOWNLOAD_IS_PROBE
Internal option used to flag this download as a 'probe' for a search result.
@ GNUNET_NO
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:438
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:562
struct GNUNET_FS_Uri * uri
URI that identifies the file that we are downloading.
Definition fs_api.h:1813
void * client_info
Context kept for the client.
Definition fs_api.h:1808
uint64_t completed
How many bytes have we already received within the specified range (DBlocks only).
Definition fs_api.h:1903
struct GNUNET_FS_SearchResult * search
Associated search (used when downloading files based on search results), or NULL for none.
Definition fs_api.h:1783
uint64_t length
How many bytes starting from offset are desired? This is NOT the overall length of the file!
Definition fs_api.h:1897
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition fs_api.h:1771
uint32_t anonymity
Desired level of anonymity.
Definition fs_api.h:1926
struct GNUNET_FS_DownloadContext * parent
Parent download (used when downloading files in directories).
Definition fs_api.h:1777
struct GNUNET_FS_Handle * h
Global FS context.
Definition fs_api.h:1761
struct GNUNET_TIME_Absolute start_time
Time download was started.
Definition fs_api.h:1916
void * upcb_cls
Closure for upcb.
Definition fs_api.h:1102
GNUNET_FS_ProgressCallback upcb
Function to call with updates on our progress.
Definition fs_api.h:1097
struct GNUNET_FS_ProgressInfo::@25::GNUNET_FS_DownloadStatusEvent download
union GNUNET_FS_ProgressInfo::@25 value
Values that depend on the event type.
struct GNUNET_FS_Handle * fsh
File-sharing handle that generated the event.

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().

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

Definition at line 1021 of file fs_download.c.

1024{
1025 struct ProcessResultClosure *prc = cls;
1026 struct DownloadRequest *dr = value;
1027 struct GNUNET_FS_DownloadContext *dc = prc->dc;
1028 struct DownloadRequest *drc;
1029 struct GNUNET_DISK_FileHandle *fh = NULL;
1032 char pt[prc->size - sizeof (struct GNUNET_CRYPTO_XSalsa20Tag)];
1033 struct GNUNET_FS_ProgressInfo pi;
1034 uint64_t off;
1035 size_t bs;
1036 size_t app;
1037 int i;
1038 struct ContentHashKey *chkarr;
1039
1040 GNUNET_log (
1042 "Received %u byte block `%s' matching pending request at depth %u and offset %llu/%llu\n",
1043 (unsigned int) prc->size,
1044 GNUNET_h2s (key),
1045 dr->depth,
1046 (unsigned long long) dr->offset,
1047 (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length));
1050 dr->offset,
1051 dr->depth);
1052 if (prc->size != bs)
1053 {
1055 &dc->emsg,
1056 "Internal error or bogus download URI (expected %llu bytes at depth %u and offset %llu/%llu, got %llu bytes)",
1057 (unsigned long long) bs,
1058 dr->depth,
1059 (unsigned long long) dr->offset,
1060 (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length),
1061 (unsigned long long) prc->size);
1063 while (NULL != dr->parent)
1064 {
1065 dr->state = BRS_ERROR;
1066 dr = dr->parent;
1067 }
1068 dr->state = BRS_ERROR;
1069 goto signal_error;
1070 }
1071
1073 GNUNET_FS_hash_to_symmetric_key (&dr->chk.key, &skey, &iv);
1074 if (-1 ==
1076 prc->data,
1077 &skey,
1078 &iv,
1079 pt))
1080 {
1081 GNUNET_break (0);
1082 dc->emsg = GNUNET_strdup (_ ("internal error decrypting content"));
1083 goto signal_error;
1084 }
1086 dr->offset,
1087 dr->depth);
1088 /* save to disk */
1089 if ((GNUNET_YES == prc->do_store) &&
1090 ((NULL != dc->filename) || (is_recursive_download (dc))) &&
1091 ((dr->depth == dc->treedepth) ||
1093 {
1094 fh = GNUNET_DISK_file_open (NULL != dc->filename ? dc->filename
1095 : dc->temp_filename,
1102 if (NULL == fh)
1103 {
1105 _ ("Download failed: could not open file `%s': %s"),
1106 dc->filename,
1107 strerror (errno));
1108 goto signal_error;
1109 }
1111 "Saving decrypted block to disk at offset %llu\n",
1112 (unsigned long long) off);
1113 if ((off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET)))
1114 {
1116 _ ("Failed to seek to offset %llu in file `%s': %s"),
1117 (unsigned long long) off,
1118 dc->filename,
1119 strerror (errno));
1120 goto signal_error;
1121 }
1122 if (prc->size != GNUNET_DISK_file_write (fh, pt, prc->size))
1123 {
1125 &dc->emsg,
1126 _ ("Failed to write block of %u bytes at offset %llu in file `%s': %s"),
1127 (unsigned int) prc->size,
1128 (unsigned long long) off,
1129 dc->filename,
1130 strerror (errno));
1131 goto signal_error;
1132 }
1134 fh = NULL;
1135 }
1136
1137 if (0 == dr->depth)
1138 {
1139 /* DBLOCK, update progress and try recursion if applicable */
1140 app = prc->size;
1141 if (dr->offset < dc->offset)
1142 {
1143 /* starting offset begins in the middle of pt,
1144 * do not count first bytes as progress */
1145 GNUNET_assert (app > (dc->offset - dr->offset));
1146 app -= (dc->offset - dr->offset);
1147 }
1148 if (dr->offset + prc->size > dc->offset + dc->length)
1149 {
1150 /* end of block is after relevant range,
1151 * do not count last bytes as progress */
1152 GNUNET_assert (app >
1153 (dr->offset + prc->size) - (dc->offset + dc->length));
1154 app -= (dr->offset + prc->size) - (dc->offset + dc->length);
1155 }
1156 dc->completed += app;
1157
1158 /* do recursive download if option is set and either meta data
1159 * says it is a directory or if no meta data is given AND filename
1160 * ends in '.gnd' (top-level case) */
1163 pt,
1164 off,
1166 dc);
1167 }
1171 pi.value.download.specifics.progress.data = pt;
1172 pi.value.download.specifics.progress.offset = dr->offset;
1173 pi.value.download.specifics.progress.data_len = prc->size;
1174 pi.value.download.specifics.progress.depth = dr->depth;
1175 pi.value.download.specifics.progress.respect_offered = prc->respect_offered;
1176 pi.value.download.specifics.progress.num_transmissions =
1177 prc->num_transmissions;
1179 GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
1180 pi.value.download.specifics.progress.block_download_duration =
1182 else
1183 pi.value.download.specifics.progress.block_download_duration =
1184 GNUNET_TIME_UNIT_ZERO; /* found locally */
1186 if (0 == dr->depth)
1187 propagate_up (dr);
1188
1189 if (dc->completed == dc->length)
1190 {
1191 /* download completed, signal */
1193 "Download completed, truncating file to desired length %llu\n",
1194 (unsigned long long) GNUNET_ntohll (
1196 /* truncate file to size (since we store IBlocks at the end) */
1197 if (NULL != dc->filename)
1198 {
1199 if (0 != truncate (dc->filename,
1202 "truncate",
1203 dc->filename);
1204 }
1205 GNUNET_assert (0 == dr->depth);
1207 }
1208 if (0 == dr->depth)
1209 {
1210 /* bottom of the tree, no child downloads possible, just sync */
1212 return GNUNET_YES;
1213 }
1214
1215 GNUNET_log (
1217 "Triggering downloads of children (this block was at depth %u and offset %llu)\n",
1218 dr->depth,
1219 (unsigned long long) dr->offset);
1220 GNUNET_assert (0 == (prc->size % sizeof(struct ContentHashKey)));
1221 chkarr = (struct ContentHashKey *) pt;
1222 for (i = dr->num_children - 1; i >= 0; i--)
1223 {
1224 drc = dr->children[i];
1225 switch (drc->state)
1226 {
1227 case BRS_INIT:
1228 if ((drc->chk_idx + 1) * sizeof(struct ContentHashKey) > prc->size)
1229 {
1230 /* 'chkarr' does not have enough space for this chk_idx;
1231 internal error! */
1232 GNUNET_break (0);
1233 GNUNET_assert (0);
1234 dc->emsg = GNUNET_strdup (_ ("internal error decoding tree"));
1235 goto signal_error;
1236 }
1237 drc->chk = chkarr[drc->chk_idx];
1238 drc->state = BRS_CHK_SET;
1241 break;
1242
1244 GNUNET_assert (0);
1245 break;
1246
1248 GNUNET_assert (0);
1249 break;
1250
1251 case BRS_RECONSTRUCT_UP:
1252 GNUNET_assert (0);
1253 break;
1254
1255 case BRS_CHK_SET:
1256 GNUNET_assert (0);
1257 break;
1258
1259 case BRS_DOWNLOAD_DOWN:
1260 GNUNET_assert (0);
1261 break;
1262
1263 case BRS_DOWNLOAD_UP:
1264 GNUNET_assert (0);
1265 break;
1266
1267 case BRS_ERROR:
1268 GNUNET_assert (0);
1269 break;
1270
1271 default:
1272 GNUNET_assert (0);
1273 break;
1274 }
1275 }
1277 return GNUNET_YES;
1278
1279signal_error:
1280 if (NULL != fh)
1283 pi.value.download.specifics.error.message = dc->emsg;
1286 dc->mq = NULL;
1288 dc->top_request = NULL;
1289 if (NULL != dc->job_queue)
1290 {
1292 dc->job_queue = NULL;
1293 }
1295 return GNUNET_NO;
1296}
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition fs_api.c:2049
void GNUNET_FS_dequeue_(struct GNUNET_FS_QueueEntry *qe)
Dequeue a job from the queue.
Definition fs_api.c:356
@ BRS_DOWNLOAD_UP
This block and all of its children have been downloaded successfully (full completion propagates up).
Definition fs_api.h:1674
@ BRS_RECONSTRUCT_META_UP
We've calculated the CHK bottom-up based on the meta data.
Definition fs_api.h:1642
@ BRS_CHK_SET
We've determined the real, desired CHK for this block (full tree reconstruction failed),...
Definition fs_api.h:1659
@ BRS_ERROR
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:1681
@ BRS_RECONSTRUCT_DOWN
We've checked the block on the path down the tree, and the content on disk did match the desired CHK,...
Definition fs_api.h:1634
@ BRS_INIT
Initial state, block has only been allocated (since it is relevant to the overall download request).
Definition fs_api.h:1626
@ BRS_DOWNLOAD_DOWN
We've successfully downloaded this block, but the children still need to be either downloaded or veri...
Definition fs_api.h:1668
@ BRS_RECONSTRUCT_UP
We'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:1650
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.
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 ...
void GNUNET_FS_free_download_request_(struct DownloadRequest *dr)
(recursively) free download request structure
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.
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:38
static void trigger_recursive_download(void *cls, const char *filename, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_MetaData *meta, size_t length, const void *data)
We found an entry in a directory.
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 w...
Definition fs_download.c:68
static void schedule_block_download(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Schedule the download of the specified block in the tree.
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:211
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_xsalsa20poly1305_decrypt(size_t in_buf_len, const unsigned char in_buf[in_buf_len], const struct GNUNET_CRYPTO_XSalsa20SecretKey *key, const struct GNUNET_CRYPTO_XSalsa20Nonce *nonce, void *out_buf)
Encrypt the given data using XSalsa20-Poly1305.
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:1308
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:745
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:219
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1386
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_OPEN_READWRITE
Open the file for both reading and writing.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_GROUP_READ
Group can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
@ GNUNET_DISK_PERM_OTHER_READ
Everybody can read.
@ GNUNET_DISK_SEEK_SET
Seek an absolute position (from the start of the file).
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.
void GNUNET_FS_hash_to_symmetric_key(const struct GNUNET_HashCode *hc, struct GNUNET_CRYPTO_XSalsa20SecretKey *skey, struct GNUNET_CRYPTO_XSalsa20Nonce *nonce)
Definition fs_api.c:3342
@ GNUNET_FS_DOWNLOAD_NO_TEMPORARIES
Do not append temporary data to the target file (for the IBlocks).
@ GNUNET_FS_STATUS_DOWNLOAD_ERROR
Notification that this download encountered an error.
@ GNUNET_FS_STATUS_DOWNLOAD_PROGRESS
Notification about progress with this download.
enum GNUNET_GenericReturnValue 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.
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
@ GNUNET_OK
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition fs.h:59
Information about an active download request.
Definition fs_api.h:1689
struct DownloadRequest ** children
Array (!) of child-requests, or NULL for the bottom of the tree.
Definition fs_api.h:1698
unsigned int chk_idx
Offset of the CHK for this block in the parent block.
Definition fs_api.h:1726
unsigned int num_children
Number of entries in children array.
Definition fs_api.h:1716
uint64_t offset
Offset of the corresponding block.
Definition fs_api.h:1711
enum BlockRequestState state
State in the FSM.
Definition fs_api.h:1731
unsigned int depth
Depth of the corresponding block in the tree.
Definition fs_api.h:1721
struct DownloadRequest * parent
Parent in the CHK-tree.
Definition fs_api.h:1693
struct ContentHashKey chk
CHK for the request for this block (set during reconstruction to what we have on disk,...
Definition fs_api.h:1704
uint64_t file_length
Total size of the file in bytes.
Definition fs_api.h:99
Handle used to access files (and pipes).
Context for controlling a download.
Definition fs_api.h:1757
unsigned int treedepth
The depth of the file-tree.
Definition fs_api.h:1931
int issue_requests
Are we ready to issue requests (reconstructions are finished)?
Definition fs_api.h:1948
uint64_t offset
What is the first offset that we're interested in?
Definition fs_api.h:1891
struct GNUNET_FS_QueueEntry * job_queue
Our entry in the job queue.
Definition fs_api.h:1847
char * emsg
Error message, NULL if we're doing OK.
Definition fs_api.h:1823
struct GNUNET_CONTAINER_MultiHashMap * active
Map of active requests (those waiting for a response).
Definition fs_api.h:1864
struct DownloadRequest * top_request
Top-level download request.
Definition fs_api.h:1869
Argument given to the progress callback with information about what is going on.
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition fs_api.h:212
union GNUNET_FS_Uri::@57 data
uint64_t abs_value_us
The actual value.
Closure for iterator processing results.
uint32_t respect_offered
how much respect did we offer to get this reply?
size_t size
Number of bytes in data.
int do_store
Flag to indicate if this block should be stored on disk.
struct GNUNET_FS_DownloadContext * dc
Our download context.
struct GNUNET_TIME_Absolute last_transmission
When did we last transmit the request?
const void * data
Data found in P2P network.
uint32_t num_transmissions
how often did we transmit the query?
struct GNUNET_HashCode query
Hash of data.

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(), GNUNET_FS_Uri::data, ProcessResultClosure::data, dc, ProcessResultClosure::dc, DownloadRequest::depth, ProcessResultClosure::do_store, GNUNET_FS_ProgressInfo::download, GNUNET_FS_DownloadContext::emsg, FileIdentifier::file_length, GNUNET_FS_DownloadContext::filename, GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_xsalsa20poly1305_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_hash_to_symmetric_key(), 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, key, 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(), size, ProcessResultClosure::size, DownloadRequest::state, GNUNET_FS_ProgressInfo::status, GNUNET_FS_DownloadContext::temp_filename, GNUNET_FS_DownloadContext::top_request, GNUNET_FS_DownloadContext::treedepth, trigger_recursive_download(), GNUNET_FS_DownloadContext::uri, value, and GNUNET_FS_ProgressInfo::value.

Referenced by encrypt_existing_match(), and handle_put().

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 213 of file fs_download.c.

219{
220 struct ProcessResultClosure prc;
221 char enc[len + sizeof (struct GNUNET_CRYPTO_XSalsa20Tag)];
224 struct GNUNET_HashCode query;
225
226 GNUNET_FS_hash_to_symmetric_key (&chk->key, &sk, &iv);
228 (unsigned char*) block,
229 &sk,
230 &iv,
231 enc))
232 {
233 GNUNET_break (0);
234 return GNUNET_SYSERR;
235 }
236 GNUNET_CRYPTO_hash (enc, sizeof enc, &query);
237 if (0 != memcmp (&query, &chk->query, sizeof(struct GNUNET_HashCode)))
238 {
239 GNUNET_break_op (0);
240 return GNUNET_SYSERR;
241 }
242 GNUNET_log (
244 "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n",
245 (unsigned int) len,
246 dc->filename,
247 (unsigned long long) dr->offset);
248 /* already got it! */
249 prc.dc = dc;
250 prc.data = enc;
251 prc.size = len;
252 prc.type = (0 == dr->depth) ? GNUNET_BLOCK_TYPE_FS_DBLOCK
254 prc.query = chk->query;
255 prc.do_store = do_store;
256 prc.last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
257 process_result_with_request (&prc, &chk->key, dr);
258 return GNUNET_OK;
259}
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.
static OpusEncoder * enc
OPUS encoder.
@ GNUNET_BLOCK_TYPE_FS_DBLOCK
Data block (leaf) in the CHK tree.
@ GNUNET_BLOCK_TYPE_FS_IBLOCK
Inner block in the CHK tree.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_xsalsa20poly1305_encrypt(size_t in_buf_len, const unsigned char in_buf[in_buf_len], const struct GNUNET_CRYPTO_XSalsa20SecretKey *key, const struct GNUNET_CRYPTO_XSalsa20Nonce *nonce, void *out_buf)
Encrypt the given data using XSalsa20-Poly1305.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition fs.h:64
A 512-bit hashcode.

References ProcessResultClosure::data, dc, ProcessResultClosure::dc, DownloadRequest::depth, ProcessResultClosure::do_store, enc, GNUNET_FS_DownloadContext::filename, GNUNET_BLOCK_TYPE_FS_DBLOCK, GNUNET_BLOCK_TYPE_FS_IBLOCK, GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_xsalsa20poly1305_encrypt(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_FS_hash_to_symmetric_key(), GNUNET_log, GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_ABS, ContentHashKey::key, ProcessResultClosure::last_transmission, DownloadRequest::offset, process_result_with_request(), ContentHashKey::query, ProcessResultClosure::query, ProcessResultClosure::size, and ProcessResultClosure::type.

Referenced by try_top_down_reconstruction().

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 1413 of file fs_download.c.

1414{
1415 if (NULL != dc->mq)
1416 {
1418 "Moving all requests back to pending list\n");
1420 dc->mq = NULL;
1421 }
1424 else
1426
1428 "Will try to reconnect in %s\n",
1430 GNUNET_YES));
1431 GNUNET_break (NULL != dc->job_queue);
1432 dc->task =
1434}
static void do_reconnect(void *cls)
Reconnect to the FS service and transmit our queries NOW.
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:1283
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:610
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
#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_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:1885
struct GNUNET_TIME_Relative reconnect_backoff
How long to wait before we try to reconnect to FS service?
Definition fs_api.h:1921
uint64_t rel_value_us
The actual value.

References dc, 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(), and download_mq_error_handler().

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_FS_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 862 of file fs_download.c.

868{
869 struct GNUNET_FS_DownloadContext *dc = cls;
870 struct GNUNET_FS_DownloadContext *cpos;
871 char *temp_name;
872 char *fn;
873 char *us;
874 char *ext;
875 char *dn;
876 char *pos;
877 char *full_name;
878 char *sfn;
879
880 if (NULL == uri)
881 return; /* entry for the directory itself */
882 cpos = dc->child_head;
883 while (NULL != cpos)
884 {
885 if ((GNUNET_FS_uri_test_equal (uri, cpos->uri)) ||
886 ((NULL != filename) && (0 == strcmp (cpos->filename, filename))))
887 break;
888 cpos = cpos->next;
889 }
890 if (NULL != cpos)
891 return; /* already exists */
892 fn = NULL;
893 if (NULL == filename)
894 {
896 if (NULL == fn)
897 {
899 fn = GNUNET_strdup (&us[strlen (GNUNET_FS_URI_CHK_PREFIX)]);
900 GNUNET_free (us);
901 }
902 else if ('.' == fn[0])
903 {
904 ext = fn;
906 GNUNET_asprintf (&fn,
907 "%s%s",
908 &us[strlen (GNUNET_FS_URI_CHK_PREFIX)],
909 ext);
910 GNUNET_free (ext);
911 GNUNET_free (us);
912 }
913 /* change '\' to '/' (this should have happened
914 * during insertion, but malicious peers may
915 * not have done this) */
916 while (NULL != (pos = strstr (fn, "\\")))
917 *pos = '/';
918 /* remove '../' everywhere (again, well-behaved
919 * peers don't do this, but don't trust that
920 * we did not get something nasty) */
921 while (NULL != (pos = strstr (fn, "../")))
922 {
923 pos[0] = '_';
924 pos[1] = '_';
925 pos[2] = '_';
926 }
927 filename = fn;
928 }
929 if (NULL == dc->filename)
930 {
931 full_name = NULL;
932 }
933 else
934 {
935 dn = GNUNET_strdup (dc->filename);
937 (strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
938 (NULL != strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
940 sfn = GNUNET_strdup (filename);
941 while ((strlen (sfn) > 0) && ('/' == filename[strlen (sfn) - 1]))
942 sfn[strlen (sfn) - 1] = '\0';
943 if ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
944 (NULL != strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
946 dn[strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT)] = '\0';
948 ((strlen (filename) < strlen (GNUNET_FS_DIRECTORY_EXT)) ||
949 (NULL == strstr (filename + strlen (filename)
950 - strlen (GNUNET_FS_DIRECTORY_EXT),
952 {
953 GNUNET_asprintf (&full_name,
954 "%s%s%s%s",
955 dn,
957 sfn,
959 }
960 else
961 {
962 GNUNET_asprintf (&full_name, "%s%s%s", dn, DIR_SEPARATOR_STR, sfn);
963 }
964 GNUNET_free (sfn);
965 GNUNET_free (dn);
966 }
967 if ((NULL != full_name) &&
969 {
971 _ (
972 "Failed to create directory for recursive download of `%s'\n")
973 ,
974 full_name);
975 GNUNET_free (full_name);
976 GNUNET_free (fn);
977 return;
978 }
979
980 temp_name = NULL;
982 "Triggering recursive download of size %llu with %u bytes MD\n",
983 (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri),
985 meta));
987 uri,
988 meta,
989 full_name,
990 temp_name,
991 0,
993 dc->anonymity,
994 dc->options,
995 NULL,
996 dc);
997 GNUNET_free (full_name);
998 GNUNET_free (temp_name);
999 GNUNET_free (fn);
1000}
#define GNUNET_FS_URI_CHK_PREFIX
static char * filename
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static struct GNUNET_FS_MetaData * meta
Meta-data provided via command-line option.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:664
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:1360
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:1201
struct GNUNET_FS_DownloadContext * GNUNET_FS_download_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_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.
char * GNUNET_FS_uri_to_string(const struct GNUNET_FS_Uri *uri)
Convert a URI to a UTF-8 String.
Definition fs_uri.c:2034
char * GNUNET_FS_meta_data_suggest_filename(const struct GNUNET_FS_MetaData *md)
Suggest a filename based on given metadata.
Definition fs_misc.c:39
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_free(ptr)
Wrapper around free.
ssize_t GNUNET_FS_meta_data_get_serialized_size(const struct GNUNET_FS_MetaData *md)
Get the size of the full meta-data in serialized form.
Definition meta_data.c:858
#define DIR_SEPARATOR_STR
Definition platform.h:167
struct GNUNET_FS_DownloadContext * child_head
Head of list of child downloads.
Definition fs_api.h:1788
struct GNUNET_FS_DownloadContext * next
Next download belonging to the same parent.
Definition fs_api.h:1803

References _, GNUNET_FS_DownloadContext::anonymity, GNUNET_FS_DownloadContext::child_head, dc, DIR_SEPARATOR_STR, filename, GNUNET_FS_DownloadContext::filename, GNUNET_asprintf(), GNUNET_break, GNUNET_DISK_directory_create_for_file(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_FS_DIRECTORY_EXT, GNUNET_FS_download_start(), GNUNET_FS_meta_data_get_serialized_size(), 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, meta, GNUNET_FS_DownloadContext::next, GNUNET_FS_DownloadContext::options, uri, and GNUNET_FS_DownloadContext::uri.

Referenced by full_recursive_download(), and process_result_with_request().

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 300 of file fs_download.c.

301{
302 size_t size;
303 uint64_t size64;
304 void *data;
306 struct GNUNET_DISK_MapHandle *m;
307
309 size = (size_t) size64;
310 if (size64 != (uint64_t) size)
311 {
312 GNUNET_log (
314 _ (
315 "Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n"));
316 return;
317 }
318 if (NULL != dc->filename)
319 {
323 }
324 else
325 {
326 GNUNET_assert (NULL != dc->temp_filename);
330 }
331 if (NULL == h)
332 return; /* oops */
334 if (NULL == data)
335 {
337 _ ("Directory too large for system address space\n"));
338 }
339 else
340 {
341 if (GNUNET_OK !=
343 data,
344 0,
346 dc))
347 {
348 GNUNET_log (
350 _ (
351 "Failed to access full directory contents of `%s' for recursive download\n"),
352 dc->filename);
353 }
355 }
357 if (NULL == dc->filename)
358 {
359 if (0 != unlink (dc->temp_filename))
361 "unlink",
364 dc->temp_filename = NULL;
365 }
366}
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition gnunet-arm.c:103
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static char * data
The data to insert into the dht.
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:1460
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition disk.c:1491
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
@ GNUNET_DISK_MAP_TYPE_READ
Read-only memory map.
Handle for a memory-mapping operation.
Definition disk.c:1441
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:1842

References _, data, dc, 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, size, GNUNET_FS_DownloadContext::temp_filename, trigger_recursive_download(), and GNUNET_FS_DownloadContext::uri.

Referenced by check_completed().

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 380 of file fs_download.c.

381{
382 struct GNUNET_FS_ProgressInfo pi;
383 struct GNUNET_FS_DownloadContext *pos;
384
385 /* first, check if we need to download children */
388 /* then, check if children are done already */
389 for (pos = dc->child_head; NULL != pos; pos = pos->next)
390 {
391 if ((NULL == pos->emsg) && (pos->completed < pos->length))
392 return; /* not done yet */
393 if ((NULL != pos->child_head) && (pos->has_finished != GNUNET_YES))
394 return; /* not transitively done yet */
395 }
396 /* All of our children are done, so mark this download done */
398 if (NULL != dc->job_queue)
399 {
401 dc->job_queue = NULL;
402 }
403 if (NULL != dc->task)
404 {
406 dc->task = NULL;
407 }
408 if (NULL != dc->rfh)
409 {
411 dc->rfh = NULL;
412 }
414
415 /* signal completion */
418
419 /* let parent know */
420 if (NULL != dc->parent)
422}
static void full_recursive_download(struct GNUNET_FS_DownloadContext *dc)
We're done downloading a directory.
@ GNUNET_FS_STATUS_DOWNLOAD_COMPLETED
Notification that this download completed.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
int has_finished
Flag set upon transitive completion (includes child downloads).
Definition fs_api.h:1943
struct GNUNET_DISK_FileHandle * rfh
File handle for reading data from an existing file (to pass to tree encoder).
Definition fs_api.h:1858

References check_completed(), GNUNET_FS_DownloadContext::child_head, GNUNET_FS_DownloadContext::completed, dc, 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 check_completed(), GNUNET_FS_download_start_task_(), process_result_with_request(), reconstruct_cb(), and try_match_block().

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 436 of file fs_download.c.

440{
441 struct GNUNET_FS_ProgressInfo pi;
442 unsigned int i;
443 char enc[DBLOCK_SIZE];
444 struct ContentHashKey chks[CHK_PER_INODE];
445 struct ContentHashKey in_chk;
448 size_t dlen;
449 struct DownloadRequest *drc;
450 struct GNUNET_DISK_FileHandle *fh;
451 int complete;
452 const char *fn;
453 const char *odata;
454 size_t odata_len;
455
456 odata = data;
457 odata_len = data_len;
458 if (BRS_DOWNLOAD_UP == dr->state)
459 return;
460 if (dr->depth > 0)
461 {
462 if ((dc->offset > 0) ||
464 {
465 /* NOTE: this test is not tight, but should suffice; the issue
466 here is that 'dr->num_children' may inherently only specify a
467 smaller range than what is in the original file;
468 thus, reconstruction of (some) inner blocks will fail.
469 FIXME: we might eventually want to write a tighter test to
470 maximize the circumstances under which we do succeed with
471 IBlock reconstruction. (need good tests though). */return;
472 }
473 complete = GNUNET_YES;
474 for (i = 0; i < dr->num_children; i++)
475 {
476 drc = dr->children[i];
477 try_match_block (dc, drc, data, data_len);
478 if (drc->state != BRS_RECONSTRUCT_META_UP)
479 complete = GNUNET_NO;
480 else
481 chks[i] = drc->chk;
482 }
483 if (GNUNET_YES != complete)
484 return;
485 data = (const char *) chks;
486 dlen = dr->num_children * sizeof(struct ContentHashKey);
487 }
488 else
489 {
490 if (dr->offset > data_len)
491 return; /* oops */
492 dlen = GNUNET_MIN (data_len - dr->offset, DBLOCK_SIZE);
493 }
494 GNUNET_CRYPTO_hash (&data[dr->offset], dlen, &in_chk.key);
495 GNUNET_FS_hash_to_symmetric_key (&in_chk.key, &sk, &iv);
496 if (-1 ==
498 (unsigned char*) &data[dr->offset]
499 ,
500 &sk,
501 &iv,
502 enc))
503 {
504 GNUNET_break (0);
505 return;
506 }
508 dlen + sizeof (struct GNUNET_CRYPTO_XSalsa20Tag),
509 &in_chk.query);
510 switch (dr->state)
511 {
512 case BRS_INIT:
513 dr->chk = in_chk;
515 break;
516
517 case BRS_CHK_SET:
518 if (0 != memcmp (&in_chk, &dr->chk, sizeof(struct ContentHashKey)))
519 {
520 /* other peer provided bogus meta data */
521 GNUNET_break_op (0);
522 break;
523 }
524 /* write block to disk */
525 fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
526 if (NULL != fn)
527 {
528 fh = GNUNET_DISK_file_open (fn,
536 if (NULL == fh)
537 {
540 _ ("Failed to open file `%s' for writing"),
541 fn);
543 dr->state = BRS_ERROR;
545 pi.value.download.specifics.error.message = dc->emsg;
547 return;
548 }
549 if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len))
550 {
553 _ ("Failed to open file `%s' for writing"),
554 fn);
556 dr->state = BRS_ERROR;
558 pi.value.download.specifics.error.message = dc->emsg;
560 return;
561 }
563 }
564 /* signal success */
566 dc->completed = dc->length;
569 pi.value.download.specifics.progress.data = data;
570 pi.value.download.specifics.progress.offset = 0;
571 pi.value.download.specifics.progress.data_len = dlen;
572 pi.value.download.specifics.progress.depth = 0;
573 pi.value.download.specifics.progress.respect_offered = 0;
574 pi.value.download.specifics.progress.block_download_duration =
577 if ((NULL != dc->filename) &&
578 (0 != truncate (dc->filename,
581 "truncate",
582 dc->filename);
584 break;
585
586 default:
587 /* how did we get here? */
588 GNUNET_break (0);
589 break;
590 }
591}
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).
@ GNUNET_DISK_OPEN_TRUNCATE
Truncate file if it exists.
#define GNUNET_MIN(a, b)

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, CHK_PER_INODE, GNUNET_FS_DownloadContext::completed, data, GNUNET_FS_Uri::data, DBLOCK_SIZE, dc, DownloadRequest::depth, GNUNET_FS_ProgressInfo::download, GNUNET_FS_DownloadContext::emsg, enc, FileIdentifier::file_length, GNUNET_FS_DownloadContext::filename, GNUNET_asprintf(), GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_xsalsa20poly1305_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_hash_to_symmetric_key(), 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, try_match_block(), GNUNET_FS_DownloadContext::uri, and GNUNET_FS_ProgressInfo::value.

Referenced by match_full_data(), and try_match_block().

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 (e.g. '<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 613 of file fs_download.c.

620{
621 struct GNUNET_FS_DownloadContext *dc = cls;
622
624 return 0;
626 "Found %u bytes of FD!\n",
627 (unsigned int) data_len);
628 if (GNUNET_FS_uri_chk_get_file_size (dc->uri) != data_len)
629 {
630 GNUNET_break_op (0);
631 return 1; /* bogus meta data */
632 }
633 try_match_block (dc, dc->top_request, data, data_len);
634 return 1;
635}
static uint32_t type
Type string converted to DNS type value.
@ EXTRACTOR_METATYPE_GNUNET_FULL_DATA

References data, dc, 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(), type, and GNUNET_FS_DownloadContext::uri.

Referenced by GNUNET_FS_download_start_task_().

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 645 of file fs_download.c.

646{
647 unsigned int i;
648
649 do
650 {
652 dr = dr->parent;
653 if (NULL == dr)
654 break;
655 for (i = 0; i < dr->num_children; i++)
656 if (dr->children[i]->state != BRS_DOWNLOAD_UP)
657 break;
658 }
659 while (i == dr->num_children);
660}

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().

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 674 of file fs_download.c.

676{
677 uint64_t off;
678 char block[DBLOCK_SIZE];
679 struct GNUNET_HashCode key;
680 uint64_t total;
681 size_t len;
682 unsigned int i;
683 struct DownloadRequest *drc;
684 uint64_t child_block_size;
685 const struct ContentHashKey *chks;
686 int up_done;
687
688 GNUNET_assert (NULL != dc->rfh);
692 len = GNUNET_FS_tree_calculate_block_size (total, dr->offset, dr->depth);
693 GNUNET_assert (len <= DBLOCK_SIZE);
694 off = compute_disk_offset (total, dr->offset, dr->depth);
695 if (dc->old_file_size < off + len)
696 return; /* failure */
698 {
700 return; /* failure */
701 }
702 if (len != GNUNET_DISK_file_read (dc->rfh, block, len))
703 {
705 return; /* failure */
706 }
707 GNUNET_CRYPTO_hash (block, len, &key);
708 if (0 != memcmp (&key, &dr->chk.key, sizeof(struct GNUNET_HashCode)))
709 return; /* mismatch */
710 if (GNUNET_OK !=
711 encrypt_existing_match (dc, &dr->chk, dr, block, len, GNUNET_NO))
712 {
713 /* hash matches but encrypted block does not, really bad */
714 dr->state = BRS_ERROR;
715 /* propagate up */
716 while (NULL != dr->parent)
717 {
718 dr = dr->parent;
719 dr->state = BRS_ERROR;
720 }
721 return;
722 }
723 /* block matches */
725
726 /* set CHKs for children */
727 up_done = GNUNET_YES;
728 chks = (const struct ContentHashKey *) block;
729 for (i = 0; i < dr->num_children; i++)
730 {
731 drc = dr->children[i];
732 GNUNET_assert (drc->offset >= dr->offset);
733 child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth);
734 GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size);
735 if (BRS_INIT == drc->state)
736 {
737 drc->state = BRS_CHK_SET;
738 drc->chk = chks[drc->chk_idx];
740 }
741 if (BRS_DOWNLOAD_UP != drc->state)
742 up_done = GNUNET_NO; /* children not all done */
743 }
744 if (GNUNET_YES == up_done)
745 propagate_up (dr); /* children all done (or no children...) */
746}
static void try_top_down_reconstruction(struct GNUNET_FS_DownloadContext *dc, struct DownloadRequest *dr)
Try top-down reconstruction.
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.
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:156
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:704
uint64_t old_file_size
What was the size of the file on disk that we're downloading before we started? Used to detect if the...
Definition fs_api.h:1911

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, dc, 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, key, ContentHashKey::key, 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, try_top_down_reconstruction(), and GNUNET_FS_DownloadContext::uri.

Referenced by GNUNET_FS_download_start_task_(), and try_top_down_reconstruction().

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 758 of file fs_download.c.

759{
760 struct GNUNET_FS_DownloadContext *dc = cls;
761 struct DownloadRequest *dr = entry;
762 struct SearchMessage *sm;
763 struct GNUNET_MQ_Envelope *env;
764
768 else
770 if (0 == dr->depth)
771 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK);
772 else
773 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK);
774 sm->anonymity_level = htonl (dc->anonymity);
775 sm->target = dc->target;
776 sm->query = dr->chk.query;
778 return GNUNET_OK;
779}
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
@ GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY
Only search the local host, do not search remote systems (no P2P)
@ GNUNET_FS_SEARCH_OPTION_NONE
No options (use defaults for everything).
@ GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY
Only download from the local host, do not access remote systems (no P2P)
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:305
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#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't know of such a peer.
Definition fs_api.h:1875
Message sent from a GNUnet (fs) search activity to the gnunet-service-fs to start a search.
Definition fs.h:270
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:307
uint32_t type
Type of the content that we're looking for.
Definition fs.h:290
struct GNUNET_HashCode query
Hash of the public key for UBLOCKs; Hash of the CHK-encoded block for DBLOCKS and IBLOCKS.
Definition fs.h:313
uint32_t anonymity_level
Desired anonymity level, big-endian.
Definition fs.h:295
uint32_t options
Bitmask with options.
Definition fs.h:285

References GNUNET_FS_DownloadContext::anonymity, SearchMessage::anonymity_level, DownloadRequest::chk, dc, 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, ContentHashKey::query, SearchMessage::query, SearchMessage::target, GNUNET_FS_DownloadContext::target, and SearchMessage::type.

Referenced by do_reconnect(), and schedule_block_download().

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 789 of file fs_download.c.

791{
792 unsigned int i;
793
794 switch (dr->state)
795 {
796 case BRS_INIT:
797 GNUNET_assert (0);
798 break;
799
801 GNUNET_assert (0);
802 break;
803
805 GNUNET_assert (0);
806 break;
807
809 GNUNET_assert (0);
810 break;
811
812 case BRS_CHK_SET:
813 /* normal case, start download */
814 break;
815
817 for (i = 0; i < dr->num_children; i++)
819 return;
820
821 case BRS_DOWNLOAD_UP:
822 /* We're done! */
823 return;
824
825 case BRS_ERROR:
826 GNUNET_break (0);
827 return;
828 }
830 "Scheduling download at offset %llu and depth %u for `%s'\n",
831 (unsigned long long) dr->offset,
832 dr->depth,
833 GNUNET_h2s (&dr->chk.query));
835 &dr->chk.query,
836 dr))
837 return; /* already active */
839 &dr->chk.query,
840 dr,
842 if (NULL == dc->mq)
843 return; /* download not active */
844 retry_entry (dc, &dr->chk.query, dr);
845}
static int retry_entry(void *cls, const struct GNUNET_HashCode *key, void *entry)
Add entries to the message queue.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue 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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.

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, dc, 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(), schedule_block_download(), and DownloadRequest::state.

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

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 1009 of file fs_download.c.

1010{
1011 if (NULL == dr)
1012 return;
1013 for (unsigned int i = 0; i < dr->num_children; i++)
1015 GNUNET_free (dr->children);
1016 GNUNET_free (dr);
1017}

References DownloadRequest::children, GNUNET_free, GNUNET_FS_free_download_request_(), and DownloadRequest::num_children.

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

Here is the call graph for this function:
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 1307 of file fs_download.c.

1308{
1309 /* any varsize length is OK */
1310 return GNUNET_OK;
1311}

References GNUNET_OK.

◆ 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 1322 of file fs_download.c.

1323{
1324 struct GNUNET_FS_DownloadContext *dc = cls;
1325 uint16_t msize = ntohs (cm->header.size) - sizeof(*cm);
1326 struct ProcessResultClosure prc;
1327
1328 prc.dc = dc;
1329 prc.data = &cm[1];
1331 prc.size = msize;
1332 prc.type = ntohl (cm->type);
1333 prc.do_store = GNUNET_YES;
1334 prc.respect_offered = ntohl (cm->respect_offered);
1335 prc.num_transmissions = ntohl (cm->num_transmissions);
1336 GNUNET_CRYPTO_hash (prc.data, msize, &prc.query);
1338 "Received result for query `%s' from FS service\n",
1339 GNUNET_h2s (&prc.query));
1341 &prc.query,
1343 &prc);
1344}
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
uint32_t respect_offered
How much respect did we offer (in total) before getting an answer (estimate).
Definition fs.h:388
uint32_t type
Type of the block (in big endian).
Definition fs.h:365
struct GNUNET_MessageHeader header
Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
Definition fs.h:360
struct GNUNET_TIME_AbsoluteNBO last_transmission
When was the last time we've tried to download this block? (FOREVER if unknown/not relevant)
Definition fs.h:376
uint32_t num_transmissions
How often did we transmit this query before getting an answer (estimate).
Definition fs.h:382

References GNUNET_FS_DownloadContext::active, ProcessResultClosure::data, dc, 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, ClientPutMessage::last_transmission, ProcessResultClosure::last_transmission, ClientPutMessage::num_transmissions, ProcessResultClosure::num_transmissions, process_result_with_request(), ProcessResultClosure::query, ClientPutMessage::respect_offered, ProcessResultClosure::respect_offered, GNUNET_MessageHeader::size, ProcessResultClosure::size, ClientPutMessage::type, and ProcessResultClosure::type.

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 1356 of file fs_download.c.

1357{
1358 struct GNUNET_FS_DownloadContext *dc = cls;
1359
1360 if (NULL != dc->mq)
1361 {
1363 dc->mq = NULL;
1364 }
1366 "Transmitting download request failed, trying to reconnect\n");
1367 try_reconnect (dc);
1368}
static void try_reconnect(struct GNUNET_FS_DownloadContext *dc)
We've lost our connection with the FS service.

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

Referenced by do_reconnect().

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 1377 of file fs_download.c.

1378{
1379 struct GNUNET_FS_DownloadContext *dc = cls;
1381 { GNUNET_MQ_hd_var_size (put,
1383 struct ClientPutMessage,
1384 dc),
1386
1387 dc->task = NULL;
1389 "fs",
1390 handlers,
1392 dc);
1393 if (NULL == dc->mq)
1394 {
1396 "Connecting to `%s'-service failed, will try again.\n",
1397 "FS");
1398 try_reconnect (dc);
1399 return;
1400 }
1402}
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
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...
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:1060
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_FS_PUT
P2P response with content or active migration of content.
Response from FS service with a result for a previous FS search.
Definition fs.h:356
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition fs_api.h:1087
Message handler for a specific message type.

References GNUNET_FS_DownloadContext::active, GNUNET_FS_Handle::cfg, dc, 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, handlers, GNUNET_FS_DownloadContext::mq, retry_entry(), GNUNET_FS_DownloadContext::task, and try_reconnect().

Referenced by activate_fs_download(), and try_reconnect().

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'

Definition at line 1443 of file fs_download.c.

1444{
1445 struct GNUNET_FS_DownloadContext *dc = cls;
1446 struct GNUNET_FS_ProgressInfo pi;
1447
1448 GNUNET_assert (NULL == dc->mq);
1449 GNUNET_assert (NULL != dc->active);
1450 do_reconnect (dc);
1451 if (NULL != dc->mq)
1452 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download activated\n");
1455}
@ GNUNET_FS_STATUS_DOWNLOAD_ACTIVE
Notification that this download is now actively being pursued (as opposed to waiting in the queue).

References GNUNET_FS_DownloadContext::active, dc, 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_().

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 1464 of file fs_download.c.

1465{
1466 struct GNUNET_FS_DownloadContext *dc = cls;
1467 struct GNUNET_FS_ProgressInfo pi;
1468
1469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download deactivated\n");
1470 if (NULL != dc->mq)
1471 {
1473 dc->mq = NULL;
1474 }
1477}
@ GNUNET_FS_STATUS_DOWNLOAD_INACTIVE
Notification that this download is no longer actively being pursued (back in the queue).

References dc, 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().

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 1500 of file fs_download.c.

1506{
1507 struct DownloadRequest *dr;
1508 unsigned int i;
1509 unsigned int head_skip;
1510 uint64_t child_block_size;
1511
1512 dr = GNUNET_new (struct DownloadRequest);
1513 dr->parent = parent;
1514 dr->depth = depth;
1515 dr->offset = dr_offset;
1516 dr->chk_idx = chk_idx;
1517 if (0 == depth)
1518 return dr;
1519 child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1);
1520
1521 /* calculate how many blocks at this level are not interesting
1522 * from the start (rounded down), either because of the requested
1523 * file offset or because this IBlock is further along */
1524 if (dr_offset < file_start_offset)
1525 {
1526 head_skip = (file_start_offset - dr_offset) / child_block_size;
1527 }
1528 else
1529 {
1530 head_skip = 0;
1531 }
1532
1533 /* calculate index of last block at this level that is interesting (rounded up) */
1534 dr->num_children =
1535 (file_start_offset + desired_length - dr_offset) / child_block_size;
1536 if (dr->num_children * child_block_size <
1537 file_start_offset + desired_length - dr_offset)
1538 dr->num_children++; /* round up */
1539 GNUNET_assert (dr->num_children > head_skip);
1540 dr->num_children -= head_skip;
1541 if (dr->num_children > CHK_PER_INODE)
1542 dr->num_children = CHK_PER_INODE; /* cap at max */
1544 "Block at offset %llu and depth %u has %u children\n",
1545 (unsigned long long) dr_offset,
1546 depth,
1547 dr->num_children);
1548
1549 /* now we can get the total number of *interesting* children for this block */
1550
1551 /* why else would we have gotten here to begin with? (that'd be a bad logic error) */
1552 GNUNET_assert (dr->num_children > 0);
1553
1555 for (i = 0; i < dr->num_children; i++)
1556 {
1557 dr->children[i] =
1559 i + head_skip,
1560 depth - 1,
1561 dr_offset + (i + head_skip) * child_block_size,
1562 file_start_offset,
1563 desired_length);
1564 }
1565 return dr;
1566}
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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.

References DownloadRequest::children, DownloadRequest::chk_idx, CHK_PER_INODE, create_download_request(), 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 create_download_request(), and GNUNET_FS_download_start_task_().

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 1576 of file fs_download.c.

1577{
1578 struct GNUNET_FS_DownloadContext *dc = cls;
1579
1580 /* clean up state from tree encoder */
1581 if (NULL != dc->task)
1582 {
1584 dc->task = NULL;
1585 }
1586 if (NULL != dc->rfh)
1587 {
1589 dc->rfh = NULL;
1590 }
1591 /* start "normal" download */
1593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting normal download\n");
1595}

References dc, 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_().

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 1604 of file fs_download.c.

1605{
1606 struct GNUNET_FS_DownloadContext *dc = cls;
1607
1608 dc->task = NULL;
1610}
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:320
struct GNUNET_FS_TreeEncoder * te
Tree encoder used for the reconstruction.
Definition fs_api.h:1852

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

Referenced by GNUNET_FS_download_start_task_(), and reconstruct_cb().

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 1631 of file fs_download.c.

1638{
1639 struct GNUNET_FS_DownloadContext *dc = cls;
1640 struct GNUNET_FS_ProgressInfo pi;
1641 struct DownloadRequest *dr;
1642 uint64_t blen;
1643 unsigned int chld;
1644
1645 /* find corresponding request entry */
1646 dr = dc->top_request;
1647 while (dr->depth > depth)
1648 {
1649 GNUNET_assert (dr->num_children > 0);
1650 blen = GNUNET_FS_tree_compute_tree_size (dr->depth - 1);
1651 chld = (offset - dr->offset) / blen;
1652 if (chld < dr->children[0]->chk_idx)
1653 {
1655 "Block %u < %u irrelevant for our range\n",
1656 chld,
1657 dr->children[0]->chk_idx);
1659 return; /* irrelevant block */
1660 }
1661 if (chld > dr->children[dr->num_children - 1]->chk_idx)
1662 {
1664 "Block %u > %u irrelevant for our range\n",
1665 chld,
1666 dr->children[dr->num_children - 1]->chk_idx);
1668 return; /* irrelevant block */
1669 }
1670 dr = dr->children[chld - dr->children[0]->chk_idx];
1671 }
1672 GNUNET_log (
1674 "Matched TE block with request at offset %llu and depth %u in state %d\n",
1675 (unsigned long long) dr->offset,
1676 dr->depth,
1677 dr->state);
1678 /* FIXME: this code needs more testing and might
1679 need to handle more states... */
1680 switch (dr->state)
1681 {
1682 case BRS_INIT:
1683 break;
1684
1686 break;
1687
1689 break;
1690
1691 case BRS_RECONSTRUCT_UP:
1692 break;
1693
1694 case BRS_CHK_SET:
1695 if (0 == memcmp (chk, &dr->chk, sizeof(struct ContentHashKey)))
1696 {
1697 GNUNET_log (
1699 "Reconstruction succeeded, can use block at offset %llu, depth %u\n",
1700 (unsigned long long) offset,
1701 depth);
1702 /* block matches, hence tree below matches;
1703 * this request is done! */
1704 dr->state = BRS_DOWNLOAD_UP;
1706 &dr->chk.query,
1707 dr);
1708 /* calculate how many bytes of payload this block
1709 * corresponds to */
1711 /* how many of those bytes are in the requested range? */
1712 blen = GNUNET_MIN (blen, dc->length + dc->offset - dr->offset);
1713 /* signal progress */
1714 dc->completed += blen;
1716 pi.value.download.specifics.progress.data = NULL;
1717 pi.value.download.specifics.progress.offset = offset;
1718 pi.value.download.specifics.progress.data_len = 0;
1719 pi.value.download.specifics.progress.depth = 0;
1720 pi.value.download.specifics.progress.respect_offered = 0;
1721 pi.value.download.specifics.progress.block_download_duration =
1724 /* FIXME: duplicated code from 'process_result_with_request - refactor */
1725 if (dc->completed == dc->length)
1726 {
1727 /* download completed, signal */
1729 "Download completed, truncating file to desired length %llu\n",
1730 (unsigned long long) GNUNET_ntohll (
1732 /* truncate file to size (since we store IBlocks at the end) */
1733 if (NULL != dc->filename)
1734 {
1735 if (0 != truncate (dc->filename,
1738 "truncate",
1739 dc->filename);
1740 }
1741 }
1742 }
1743 else
1744 GNUNET_log (
1746 "Reconstruction failed, need to download block at offset %llu, depth %u\n",
1747 (unsigned long long) offset,
1748 depth);
1749 break;
1750
1751 case BRS_DOWNLOAD_DOWN:
1752 break;
1753
1754 case BRS_DOWNLOAD_UP:
1755 break;
1756
1757 case BRS_ERROR:
1758 break;
1759
1760 default:
1761 GNUNET_assert (0);
1762 break;
1763 }
1765 if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP))
1767}
static void get_next_block(void *cls)
Task requesting the next block from the tree encoder.
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:1310

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, dc, 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, GNUNET_FS_DownloadContext::uri, and GNUNET_FS_ProgressInfo::value.

Referenced by GNUNET_FS_download_start_task_().

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 1783 of file fs_download.c.

1784{
1785 struct GNUNET_FS_DownloadContext *dc = cls;
1786 struct GNUNET_DISK_FileHandle *fh = dc->rfh;
1787 ssize_t ret;
1788
1789 if (NULL != emsg)
1790 *emsg = NULL;
1791 if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET))
1792 {
1793 if (NULL != emsg)
1794 *emsg = GNUNET_strdup (strerror (errno));
1795 return 0;
1796 }
1797 ret = GNUNET_DISK_file_read (fh, buf, max);
1798 if (ret < 0)
1799 {
1800 if (NULL != emsg)
1801 *emsg = GNUNET_strdup (strerror (errno));
1802 return 0;
1803 }
1804 return ret;
1805}
static int ret
Final status code.
Definition gnunet-arm.c:93
#define max(x, y)

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

Referenced by GNUNET_FS_download_start_task_().

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 1815 of file fs_download.c.

1816{
1817 struct GNUNET_FS_DownloadContext *dc = cls;
1818 struct GNUNET_FS_ProgressInfo pi;
1819 struct GNUNET_DISK_FileHandle *fh;
1820
1821 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start task running...\n");
1822 dc->task = NULL;
1823 if (0 == dc->length)
1824 {
1825 /* no bytes required! */
1826 if (NULL != dc->filename)
1827 {
1831 | ((0 ==
1834 : 0),
1840 }
1843 pi.value.download.specifics.start.meta = dc->meta;
1846 return;
1847 }
1848 if (NULL != dc->emsg)
1849 return;
1850 if (NULL == dc->top_request)
1851 {
1853 0,
1854 dc->treedepth - 1,
1855 0,
1856 dc->offset,
1857 dc->length);
1860 ? dc->uri->data.chk.chk
1861 : dc->uri->data.loc.fi.chk;
1862 /* signal start */
1864 if (NULL != dc->search)
1867 pi.value.download.specifics.start.meta = dc->meta;
1869 }
1871 /* attempt reconstruction from disk */
1877 {
1878 if (NULL != dc->rfh)
1879 {
1880 /* first, try top-down */
1882 "Trying top-down reconstruction for `%s'\n",
1883 dc->filename);
1885 switch (dc->top_request->state)
1886 {
1887 case BRS_CHK_SET:
1888 break; /* normal */
1889
1890 case BRS_DOWNLOAD_DOWN:
1891 break; /* normal, some blocks already down */
1892
1893 case BRS_DOWNLOAD_UP:
1894 /* already done entirely, party! */
1895 if (NULL != dc->rfh)
1896 {
1897 /* avoid hanging on to file handle longer than
1898 * necessary */
1900 dc->rfh = NULL;
1901 }
1902 return;
1903
1904 case BRS_ERROR:
1905 GNUNET_asprintf (&dc->emsg, _ ("Invalid URI"));
1908 pi.value.download.specifics.error.message = dc->emsg;
1910 return;
1911
1912 default:
1913 GNUNET_assert (0);
1914 break;
1915 }
1916 }
1917 }
1918 /* attempt reconstruction from meta data */
1920 (NULL != dc->meta))
1921 {
1922 GNUNET_log (
1924 "Trying to find embedded meta data for download of size %llu with %u bytes MD\n",
1925 (unsigned long long) GNUNET_FS_uri_chk_get_file_size (dc->uri),
1929 {
1930 if (NULL != dc->rfh)
1931 {
1932 /* avoid hanging on to file handle longer than
1933 * necessary */
1935 dc->rfh = NULL;
1936 }
1937 return; /* finished, status update was already done for us */
1938 }
1939 }
1940 if (NULL != dc->rfh)
1941 {
1942 /* finally, actually run bottom-up */
1944 "Trying bottom-up reconstruction of file `%s'\n",
1945 dc->filename);
1946 dc->te =
1949 dc,
1950 &fh_reader,
1952 NULL,
1955 }
1956 else
1957 {
1958 /* simple, top-level download */
1961 }
1964}
void GNUNET_FS_search_result_sync_(struct GNUNET_FS_SearchResult *sr)
Synchronize this search result with its mirror on disk.
Definition fs_api.c:2165
#define MAX_INLINE_SIZE
Maximum size for a file to be considered for inlining in a directory.
Definition fs_api.h:50
@ GNUNET_FS_URI_CHK
Content-hash-key (simple file).
Definition fs_api.h:144
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.
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 ...
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.
static void reconstruct_cont(void *cls)
Continuation after a possible attempt to reconstruct the current IBlock from the existing file.
void GNUNET_FS_download_start_downloading_(struct GNUNET_FS_DownloadContext *dc)
Start the downloading process (by entering the queue).
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:258
enum GNUNET_GenericReturnValue 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:557
@ GNUNET_FS_STATUS_DOWNLOAD_START
Notification that we have started this download.
int GNUNET_FS_meta_data_iterate(const struct GNUNET_FS_MetaData *md, EXTRACTOR_MetaDataProcessor iter, void *iter_cls)
Iterate over MD entries.
Definition meta_data.c:418
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition fs_api.h:104
enum GNUNET_FS_UriType type
Type of the URI.
Definition fs_api.h:171

References _, BRS_CHK_SET, BRS_DOWNLOAD_DOWN, BRS_DOWNLOAD_UP, BRS_ERROR, check_completed(), FileIdentifier::chk, GNUNET_FS_Uri::chk, DownloadRequest::chk, create_download_request(), GNUNET_FS_Uri::data, dc, GNUNET_FS_ProgressInfo::download, GNUNET_FS_DownloadContext::emsg, fh_reader(), Location::fi, GNUNET_FS_DownloadContext::filename, get_next_block(), GNUNET_asprintf(), GNUNET_assert, 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_meta_data_get_serialized_size(), GNUNET_FS_meta_data_iterate(), 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().

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 1968 of file fs_download.c.

1969{
1970 struct GNUNET_FS_DownloadContext *dc = cls;
1971 struct GNUNET_FS_ProgressInfo pi;
1972
1973 if (NULL != dc->top)
1975 while (NULL != dc->child_head)
1977 if (NULL != dc->search)
1978 {
1979 dc->search->download = NULL;
1980 dc->search = NULL;
1981 }
1982 if (NULL != dc->job_queue)
1983 {
1985 dc->job_queue = NULL;
1986 }
1987 if (NULL != dc->parent)
1990 dc);
1991 if (NULL != dc->task)
1992 {
1994 dc->task = NULL;
1995 }
1998 if (NULL != dc->te)
1999 {
2001 dc->te = NULL;
2002 }
2003 if (NULL != dc->rfh)
2004 {
2006 dc->rfh = NULL;
2007 }
2009 if (NULL != dc->active)
2010 {
2012 dc->active = NULL;
2013 }
2019 GNUNET_assert (NULL == dc->job_queue);
2020 GNUNET_free (dc);
2021}
void GNUNET_FS_end_top(struct GNUNET_FS_Handle *h, struct TopLevelActivity *top)
Destroy a top-level activity entry.
Definition fs_api.c:402
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...
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:442
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition fs_uri.c:677
@ GNUNET_FS_STATUS_DOWNLOAD_SUSPEND
Notification that this download was suspended.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_FS_meta_data_destroy(struct GNUNET_FS_MetaData *md)
Free meta data.
Definition meta_data.c:166
struct GNUNET_FS_DownloadContext * child_tail
Tail of list of child downloads.
Definition fs_api.h:1793
char * serialization
Random portion of filename we use for syncing state of this download.
Definition fs_api.h:1829
struct TopLevelActivity * top
Our top-level activity entry (if we are top-level, otherwise NULL).
Definition fs_api.h:1766
struct GNUNET_FS_DownloadContext * download
ID of an associated download based on this search result (or NULL for none).
Definition fs_api.h:546

References GNUNET_FS_DownloadContext::active, GNUNET_FS_DownloadContext::child_head, GNUNET_FS_DownloadContext::child_tail, dc, GNUNET_FS_SearchResult::download, GNUNET_FS_DownloadContext::filename, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_DISK_file_close(), GNUNET_free, GNUNET_FS_dequeue_(), GNUNET_FS_download_make_status_(), GNUNET_FS_download_signal_suspend_(), GNUNET_FS_end_top(), GNUNET_FS_free_download_request_(), GNUNET_FS_meta_data_destroy(), 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_signal_suspend_(), GNUNET_FS_download_start(), search_result_stop(), and search_result_suspend().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_download_context()

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

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 2044 of file fs_download.c.

2054{
2056
2058 if ((offset + length < offset) ||
2060 {
2061 GNUNET_break (0);
2062 return NULL;
2063 }
2066 "Starting download %p, %u bytes at offset %llu\n",
2067 dc,
2068 (unsigned int) length,
2069 (unsigned long long) offset);
2070 dc->h = h;
2073 dc->client_info = cctx;
2075 if (NULL != filename)
2076 {
2080 &dc->old_file_size,
2081 GNUNET_YES,
2082 GNUNET_YES));
2083 }
2087 dc->offset = offset;
2088 dc->length = length;
2090 dc->options = options;
2091 dc->active =
2093 GNUNET_NO);
2094 dc->treedepth =
2096 if ((NULL == filename) && (is_recursive_download (dc)))
2097 {
2098 if (NULL != tempname)
2099 dc->temp_filename = GNUNET_strdup (tempname);
2100 else
2101 dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp");
2102 }
2104 "Starting download `%s' of %llu bytes with tree depth %u\n",
2105 filename,
2106 (unsigned long long) length,
2107 dc->treedepth);
2108 GNUNET_assert (NULL == dc->job_queue);
2110 return dc;
2111}
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
void GNUNET_FS_download_start_task_(void *cls)
Task that creates the initial (top-level) download request for the file.
unsigned int GNUNET_FS_compute_depth(uint64_t flen)
Compute the depth of the CHK tree.
Definition fs_tree.c:125
static unsigned int anonymity
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition disk.c:439
enum GNUNET_GenericReturnValue 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:235
struct GNUNET_FS_Uri * GNUNET_FS_uri_dup(const struct GNUNET_FS_Uri *uri)
Duplicate URI.
Definition fs_uri.c:987
int GNUNET_FS_uri_test_loc(const struct GNUNET_FS_Uri *uri)
Is this a location URI?
Definition fs_uri.c:1401
int GNUNET_FS_uri_test_chk(const struct GNUNET_FS_Uri *uri)
Is this a file (or directory) URI?
Definition fs_uri.c:1346
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:812
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_FS_MetaData * GNUNET_FS_meta_data_duplicate(const struct GNUNET_FS_MetaData *md)
Duplicate a MetaData token.
Definition meta_data.c:527
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111

References GNUNET_FS_DownloadContext::active, anonymity, GNUNET_FS_DownloadContext::anonymity, GNUNET_FS_DownloadContext::client_info, DBLOCK_SIZE, dc, filename, GNUNET_FS_DownloadContext::filename, GNUNET_assert, GNUNET_break, 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_meta_data_duplicate(), 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, meta, 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, uri, and GNUNET_FS_DownloadContext::uri.

Referenced by GNUNET_FS_download_start(), and GNUNET_FS_download_start_from_search().

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 2199 of file fs_download.c.

2200{
2201 if (dc->completed == dc->length)
2202 return;
2203 if (NULL != dc->mq)
2204 return; /* already running */
2205 GNUNET_assert (NULL == dc->job_queue);
2206 GNUNET_assert (NULL == dc->task);
2207 GNUNET_assert (NULL != dc->active);
2208 dc->job_queue =
2212 dc,
2213 (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE,
2218 "Download %p put into queue as job %p\n",
2219 dc,
2220 dc->job_queue);
2221}
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:321
@ GNUNET_FS_QUEUE_PRIORITY_NORMAL
Default priority.
Definition fs_api.h:413
@ GNUNET_FS_QUEUE_PRIORITY_PROBE
This is a probe (low priority).
Definition fs_api.h:408
static void activate_fs_download(void *cls)
We're allowed to ask the FS service for our blocks.
static void deactivate_fs_download(void *cls)
We must stop to ask the FS service for our blocks.

References activate_fs_download(), GNUNET_FS_DownloadContext::active, GNUNET_FS_DownloadContext::completed, DBLOCK_SIZE, dc, 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_().

Here is the call graph for this function:
Here is the caller graph for this function: