GNUnet 0.28.0-dev.2-27-gc87478450
 
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 854 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 1027 of file fs_download.c.

1030{
1031 struct ProcessResultClosure *prc = cls;
1032 struct DownloadRequest *dr = value;
1033 struct GNUNET_FS_DownloadContext *dc = prc->dc;
1034 struct DownloadRequest *drc;
1035 struct GNUNET_DISK_FileHandle *fh = NULL;
1036 struct GNUNET_CRYPTO_AeadSecretKey skey;
1037 struct GNUNET_CRYPTO_AeadNonce iv;
1038 char pt[prc->size - sizeof (struct GNUNET_CRYPTO_AeadMac)];
1039 struct GNUNET_FS_ProgressInfo pi;
1040 uint64_t off;
1041 size_t bs;
1042 size_t app;
1043 int i;
1044 struct ContentHashKey *chkarr;
1045
1046 GNUNET_log (
1048 "Received %u byte block `%s' matching pending request at depth %u and offset %llu/%llu\n",
1049 (unsigned int) prc->size,
1050 GNUNET_h2s (key),
1051 dr->depth,
1052 (unsigned long long) dr->offset,
1053 (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length));
1056 dr->offset,
1057 dr->depth);
1058 if (prc->size != bs)
1059 {
1061 &dc->emsg,
1062 "Internal error or bogus download URI (expected %llu bytes at depth %u and offset %llu/%llu, got %llu bytes)",
1063 (unsigned long long) bs,
1064 dr->depth,
1065 (unsigned long long) dr->offset,
1066 (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length),
1067 (unsigned long long) prc->size);
1069 while (NULL != dr->parent)
1070 {
1071 dr->state = BRS_ERROR;
1072 dr = dr->parent;
1073 }
1074 dr->state = BRS_ERROR;
1075 goto signal_error;
1076 }
1077
1079 GNUNET_FS_hash_to_symmetric_key (&dr->chk.key, &skey, &iv);
1080 if (GNUNET_OK !=
1082 prc->data,
1083 0,
1084 NULL,
1085 &skey,
1086 &iv,
1087 prc->data + prc->size,
1088 pt))
1089 {
1090 GNUNET_break (0);
1091 dc->emsg = GNUNET_strdup (_ ("internal error decrypting content"));
1092 goto signal_error;
1093 }
1095 dr->offset,
1096 dr->depth);
1097 /* save to disk */
1098 if ((GNUNET_YES == prc->do_store) &&
1099 ((NULL != dc->filename) || (is_recursive_download (dc))) &&
1100 ((dr->depth == dc->treedepth) ||
1102 {
1103 fh = GNUNET_DISK_file_open (NULL != dc->filename ? dc->filename
1104 : dc->temp_filename,
1111 if (NULL == fh)
1112 {
1114 _ ("Download failed: could not open file `%s': %s"),
1115 dc->filename,
1116 strerror (errno));
1117 goto signal_error;
1118 }
1120 "Saving decrypted block to disk at offset %llu\n",
1121 (unsigned long long) off);
1122 if ((off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET)))
1123 {
1125 _ ("Failed to seek to offset %llu in file `%s': %s"),
1126 (unsigned long long) off,
1127 dc->filename,
1128 strerror (errno));
1129 goto signal_error;
1130 }
1131 if (prc->size != GNUNET_DISK_file_write (fh, pt, prc->size))
1132 {
1134 &dc->emsg,
1135 _ ("Failed to write block of %u bytes at offset %llu in file `%s': %s"),
1136 (unsigned int) prc->size,
1137 (unsigned long long) off,
1138 dc->filename,
1139 strerror (errno));
1140 goto signal_error;
1141 }
1143 fh = NULL;
1144 }
1145
1146 if (0 == dr->depth)
1147 {
1148 /* DBLOCK, update progress and try recursion if applicable */
1149 app = prc->size;
1150 if (dr->offset < dc->offset)
1151 {
1152 /* starting offset begins in the middle of pt,
1153 * do not count first bytes as progress */
1154 GNUNET_assert (app > (dc->offset - dr->offset));
1155 app -= (dc->offset - dr->offset);
1156 }
1157 if (dr->offset + prc->size > dc->offset + dc->length)
1158 {
1159 /* end of block is after relevant range,
1160 * do not count last bytes as progress */
1161 GNUNET_assert (app >
1162 (dr->offset + prc->size) - (dc->offset + dc->length));
1163 app -= (dr->offset + prc->size) - (dc->offset + dc->length);
1164 }
1165 dc->completed += app;
1166
1167 /* do recursive download if option is set and either meta data
1168 * says it is a directory or if no meta data is given AND filename
1169 * ends in '.gnd' (top-level case) */
1172 pt,
1173 off,
1175 dc);
1176 }
1180 pi.value.download.specifics.progress.data = pt;
1181 pi.value.download.specifics.progress.offset = dr->offset;
1182 pi.value.download.specifics.progress.data_len = prc->size;
1183 pi.value.download.specifics.progress.depth = dr->depth;
1184 pi.value.download.specifics.progress.respect_offered = prc->respect_offered;
1185 pi.value.download.specifics.progress.num_transmissions =
1186 prc->num_transmissions;
1188 GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
1189 pi.value.download.specifics.progress.block_download_duration =
1191 else
1192 pi.value.download.specifics.progress.block_download_duration =
1193 GNUNET_TIME_UNIT_ZERO; /* found locally */
1195 if (0 == dr->depth)
1196 propagate_up (dr);
1197
1198 if (dc->completed == dc->length)
1199 {
1200 /* download completed, signal */
1202 "Download completed, truncating file to desired length %llu\n",
1203 (unsigned long long) GNUNET_ntohll (
1205 /* truncate file to size (since we store IBlocks at the end) */
1206 if (NULL != dc->filename)
1207 {
1208 if (0 != truncate (dc->filename,
1211 "truncate",
1212 dc->filename);
1213 }
1214 GNUNET_assert (0 == dr->depth);
1216 }
1217 if (0 == dr->depth)
1218 {
1219 /* bottom of the tree, no child downloads possible, just sync */
1221 return GNUNET_YES;
1222 }
1223
1224 GNUNET_log (
1226 "Triggering downloads of children (this block was at depth %u and offset %llu)\n",
1227 dr->depth,
1228 (unsigned long long) dr->offset);
1229 GNUNET_assert (0 == (prc->size % sizeof(struct ContentHashKey)));
1230 chkarr = (struct ContentHashKey *) pt;
1231 for (i = dr->num_children - 1; i >= 0; i--)
1232 {
1233 drc = dr->children[i];
1234 switch (drc->state)
1235 {
1236 case BRS_INIT:
1237 if ((drc->chk_idx + 1) * sizeof(struct ContentHashKey) > prc->size)
1238 {
1239 /* 'chkarr' does not have enough space for this chk_idx;
1240 internal error! */
1241 GNUNET_break (0);
1242 GNUNET_assert (0);
1243 dc->emsg = GNUNET_strdup (_ ("internal error decoding tree"));
1244 goto signal_error;
1245 }
1246 drc->chk = chkarr[drc->chk_idx];
1247 drc->state = BRS_CHK_SET;
1250 break;
1251
1253 GNUNET_assert (0);
1254 break;
1255
1257 GNUNET_assert (0);
1258 break;
1259
1260 case BRS_RECONSTRUCT_UP:
1261 GNUNET_assert (0);
1262 break;
1263
1264 case BRS_CHK_SET:
1265 GNUNET_assert (0);
1266 break;
1267
1268 case BRS_DOWNLOAD_DOWN:
1269 GNUNET_assert (0);
1270 break;
1271
1272 case BRS_DOWNLOAD_UP:
1273 GNUNET_assert (0);
1274 break;
1275
1276 case BRS_ERROR:
1277 GNUNET_assert (0);
1278 break;
1279
1280 default:
1281 GNUNET_assert (0);
1282 break;
1283 }
1284 }
1286 return GNUNET_YES;
1287
1288signal_error:
1289 if (NULL != fh)
1292 pi.value.download.specifics.error.message = dc->emsg;
1295 dc->mq = NULL;
1297 dc->top_request = NULL;
1298 if (NULL != dc->job_queue)
1299 {
1301 dc->job_queue = NULL;
1302 }
1304 return GNUNET_NO;
1305}
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_aead_decrypt(size_t ct_len, const unsigned char ct[ct_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, const struct GNUNET_CRYPTO_AeadMac *mac, void *pt)
Decrypt the given data using XChaCha20-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_AeadSecretKey *skey, struct GNUNET_CRYPTO_AeadNonce *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
type for session keys
type for session keys
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_aead_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_AeadMac)];
223 struct GNUNET_CRYPTO_AeadNonce iv;
224 struct GNUNET_HashCode query;
225
226 GNUNET_FS_hash_to_symmetric_key (&chk->key, &sk, &iv);
227 if (GNUNET_OK !=
229 (unsigned char*) block,
230 0,
231 NULL,
232 &sk,
233 &iv,
234 enc,
235 (struct GNUNET_CRYPTO_AeadMac*) (enc + len)))
236 {
237 GNUNET_break (0);
238 return GNUNET_SYSERR;
239 }
240 GNUNET_CRYPTO_hash (enc, sizeof enc, &query);
241 if (0 != memcmp (&query, &chk->query, sizeof(struct GNUNET_HashCode)))
242 {
243 GNUNET_break_op (0);
244 return GNUNET_SYSERR;
245 }
246 GNUNET_log (
248 "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n",
249 (unsigned int) len,
250 dc->filename,
251 (unsigned long long) dr->offset);
252 /* already got it! */
253 prc.dc = dc;
254 prc.data = enc;
255 prc.size = len;
256 prc.type = (0 == dr->depth) ? GNUNET_BLOCK_TYPE_FS_DBLOCK
258 prc.query = chk->query;
259 prc.do_store = do_store;
260 prc.last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
261 process_result_with_request (&prc, &chk->key, dr);
262 return GNUNET_OK;
263}
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_aead_encrypt(size_t pt_len, const unsigned char pt[pt_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, void *ct, struct GNUNET_CRYPTO_AeadMac *mac)
Encrypt the given data using XChaCha20-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_aead_encrypt(), GNUNET_CRYPTO_hash(), 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 1422 of file fs_download.c.

1423{
1424 if (NULL != dc->mq)
1425 {
1427 "Moving all requests back to pending list\n");
1429 dc->mq = NULL;
1430 }
1433 else
1435
1437 "Will try to reconnect in %s\n",
1439 GNUNET_YES));
1440 GNUNET_break (NULL != dc->job_queue);
1441 dc->task =
1443}
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 868 of file fs_download.c.

874{
875 struct GNUNET_FS_DownloadContext *dc = cls;
876 struct GNUNET_FS_DownloadContext *cpos;
877 char *temp_name;
878 char *fn;
879 char *us;
880 char *ext;
881 char *dn;
882 char *pos;
883 char *full_name;
884 char *sfn;
885
886 if (NULL == uri)
887 return; /* entry for the directory itself */
888 cpos = dc->child_head;
889 while (NULL != cpos)
890 {
891 if ((GNUNET_FS_uri_test_equal (uri, cpos->uri)) ||
892 ((NULL != filename) && (0 == strcmp (cpos->filename, filename))))
893 break;
894 cpos = cpos->next;
895 }
896 if (NULL != cpos)
897 return; /* already exists */
898 fn = NULL;
899 if (NULL == filename)
900 {
902 if (NULL == fn)
903 {
905 fn = GNUNET_strdup (&us[strlen (GNUNET_FS_URI_CHK_PREFIX)]);
906 GNUNET_free (us);
907 }
908 else if ('.' == fn[0])
909 {
910 ext = fn;
912 GNUNET_asprintf (&fn,
913 "%s%s",
914 &us[strlen (GNUNET_FS_URI_CHK_PREFIX)],
915 ext);
916 GNUNET_free (ext);
917 GNUNET_free (us);
918 }
919 /* change '\' to '/' (this should have happened
920 * during insertion, but malicious peers may
921 * not have done this) */
922 while (NULL != (pos = strstr (fn, "\\")))
923 *pos = '/';
924 /* remove '../' everywhere (again, well-behaved
925 * peers don't do this, but don't trust that
926 * we did not get something nasty) */
927 while (NULL != (pos = strstr (fn, "../")))
928 {
929 pos[0] = '_';
930 pos[1] = '_';
931 pos[2] = '_';
932 }
933 filename = fn;
934 }
935 if (NULL == dc->filename)
936 {
937 full_name = NULL;
938 }
939 else
940 {
941 dn = GNUNET_strdup (dc->filename);
943 (strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
944 (NULL != strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
946 sfn = GNUNET_strdup (filename);
947 while ((strlen (sfn) > 0) && ('/' == filename[strlen (sfn) - 1]))
948 sfn[strlen (sfn) - 1] = '\0';
949 if ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
950 (NULL != strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
952 dn[strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT)] = '\0';
954 ((strlen (filename) < strlen (GNUNET_FS_DIRECTORY_EXT)) ||
955 (NULL == strstr (filename + strlen (filename)
956 - strlen (GNUNET_FS_DIRECTORY_EXT),
958 {
959 GNUNET_asprintf (&full_name,
960 "%s%s%s%s",
961 dn,
963 sfn,
965 }
966 else
967 {
968 GNUNET_asprintf (&full_name, "%s%s%s", dn, DIR_SEPARATOR_STR, sfn);
969 }
970 GNUNET_free (sfn);
971 GNUNET_free (dn);
972 }
973 if ((NULL != full_name) &&
975 {
977 _ (
978 "Failed to create directory for recursive download of `%s'\n")
979 ,
980 full_name);
981 GNUNET_free (full_name);
982 GNUNET_free (fn);
983 return;
984 }
985
986 temp_name = NULL;
988 "Triggering recursive download of size %llu with %u bytes MD\n",
989 (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri),
991 meta));
993 uri,
994 meta,
995 full_name,
996 temp_name,
997 0,
999 dc->anonymity,
1000 dc->options,
1001 NULL,
1002 dc);
1003 GNUNET_free (full_name);
1004 GNUNET_free (temp_name);
1005 GNUNET_free (fn);
1006}
#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 304 of file fs_download.c.

305{
306 size_t size;
307 uint64_t size64;
308 void *data;
310 struct GNUNET_DISK_MapHandle *m;
311
313 size = (size_t) size64;
314 if (size64 != (uint64_t) size)
315 {
316 GNUNET_log (
318 _ (
319 "Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n"));
320 return;
321 }
322 if (NULL != dc->filename)
323 {
327 }
328 else
329 {
330 GNUNET_assert (NULL != dc->temp_filename);
334 }
335 if (NULL == h)
336 return; /* oops */
338 if (NULL == data)
339 {
341 _ ("Directory too large for system address space\n"));
342 }
343 else
344 {
345 if (GNUNET_OK !=
347 data,
348 0,
350 dc))
351 {
352 GNUNET_log (
354 _ (
355 "Failed to access full directory contents of `%s' for recursive download\n"),
356 dc->filename);
357 }
359 }
361 if (NULL == dc->filename)
362 {
363 if (0 != unlink (dc->temp_filename))
365 "unlink",
368 dc->temp_filename = NULL;
369 }
370}
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 384 of file fs_download.c.

385{
386 struct GNUNET_FS_ProgressInfo pi;
387 struct GNUNET_FS_DownloadContext *pos;
388
389 /* first, check if we need to download children */
392 /* then, check if children are done already */
393 for (pos = dc->child_head; NULL != pos; pos = pos->next)
394 {
395 if ((NULL == pos->emsg) && (pos->completed < pos->length))
396 return; /* not done yet */
397 if ((NULL != pos->child_head) && (pos->has_finished != GNUNET_YES))
398 return; /* not transitively done yet */
399 }
400 /* All of our children are done, so mark this download done */
402 if (NULL != dc->job_queue)
403 {
405 dc->job_queue = NULL;
406 }
407 if (NULL != dc->task)
408 {
410 dc->task = NULL;
411 }
412 if (NULL != dc->rfh)
413 {
415 dc->rfh = NULL;
416 }
418
419 /* signal completion */
422
423 /* let parent know */
424 if (NULL != dc->parent)
426}
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 440 of file fs_download.c.

444{
445 struct GNUNET_FS_ProgressInfo pi;
446 unsigned int i;
447 char enc[DBLOCK_SIZE];
448 struct ContentHashKey chks[CHK_PER_INODE];
449 struct ContentHashKey in_chk;
451 struct GNUNET_CRYPTO_AeadNonce iv;
452 size_t dlen;
453 struct DownloadRequest *drc;
454 struct GNUNET_DISK_FileHandle *fh;
455 int complete;
456 const char *fn;
457 const char *odata;
458 size_t odata_len;
459
460 odata = data;
461 odata_len = data_len;
462 if (BRS_DOWNLOAD_UP == dr->state)
463 return;
464 if (dr->depth > 0)
465 {
466 if ((dc->offset > 0) ||
468 {
469 /* NOTE: this test is not tight, but should suffice; the issue
470 here is that 'dr->num_children' may inherently only specify a
471 smaller range than what is in the original file;
472 thus, reconstruction of (some) inner blocks will fail.
473 FIXME: we might eventually want to write a tighter test to
474 maximize the circumstances under which we do succeed with
475 IBlock reconstruction. (need good tests though). */return;
476 }
477 complete = GNUNET_YES;
478 for (i = 0; i < dr->num_children; i++)
479 {
480 drc = dr->children[i];
481 try_match_block (dc, drc, data, data_len);
482 if (drc->state != BRS_RECONSTRUCT_META_UP)
483 complete = GNUNET_NO;
484 else
485 chks[i] = drc->chk;
486 }
487 if (GNUNET_YES != complete)
488 return;
489 data = (const char *) chks;
490 dlen = dr->num_children * sizeof(struct ContentHashKey);
491 }
492 else
493 {
494 if (dr->offset > data_len)
495 return; /* oops */
496 dlen = GNUNET_MIN (data_len - dr->offset, DBLOCK_SIZE);
497 }
498 GNUNET_CRYPTO_hash (&data[dr->offset], dlen, &in_chk.key);
499 GNUNET_FS_hash_to_symmetric_key (&in_chk.key, &sk, &iv);
500 if (GNUNET_OK !=
502 (unsigned char*) &data[dr->offset],
503 0,
504 NULL,
505 &sk,
506 &iv,
507 enc,
508 (struct GNUNET_CRYPTO_AeadMac*) (enc + dlen)))
509 {
510 GNUNET_break (0);
511 return;
512 }
514 dlen + sizeof (struct GNUNET_CRYPTO_AeadMac),
515 &in_chk.query);
516 switch (dr->state)
517 {
518 case BRS_INIT:
519 dr->chk = in_chk;
521 break;
522
523 case BRS_CHK_SET:
524 if (0 != memcmp (&in_chk, &dr->chk, sizeof(struct ContentHashKey)))
525 {
526 /* other peer provided bogus meta data */
527 GNUNET_break_op (0);
528 break;
529 }
530 /* write block to disk */
531 fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
532 if (NULL != fn)
533 {
534 fh = GNUNET_DISK_file_open (fn,
542 if (NULL == fh)
543 {
546 _ ("Failed to open file `%s' for writing"),
547 fn);
549 dr->state = BRS_ERROR;
551 pi.value.download.specifics.error.message = dc->emsg;
553 return;
554 }
555 if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len))
556 {
559 _ ("Failed to open file `%s' for writing"),
560 fn);
562 dr->state = BRS_ERROR;
564 pi.value.download.specifics.error.message = dc->emsg;
566 return;
567 }
569 }
570 /* signal success */
572 dc->completed = dc->length;
575 pi.value.download.specifics.progress.data = data;
576 pi.value.download.specifics.progress.offset = 0;
577 pi.value.download.specifics.progress.data_len = dlen;
578 pi.value.download.specifics.progress.depth = 0;
579 pi.value.download.specifics.progress.respect_offered = 0;
580 pi.value.download.specifics.progress.block_download_duration =
583 if ((NULL != dc->filename) &&
584 (0 != truncate (dc->filename,
587 "truncate",
588 dc->filename);
590 break;
591
592 default:
593 /* how did we get here? */
594 GNUNET_break (0);
595 break;
596 }
597}
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_aead_encrypt(), GNUNET_CRYPTO_hash(), 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_OK, 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 619 of file fs_download.c.

626{
627 struct GNUNET_FS_DownloadContext *dc = cls;
628
630 return 0;
632 "Found %u bytes of FD!\n",
633 (unsigned int) data_len);
634 if (GNUNET_FS_uri_chk_get_file_size (dc->uri) != data_len)
635 {
636 GNUNET_break_op (0);
637 return 1; /* bogus meta data */
638 }
639 try_match_block (dc, dc->top_request, data, data_len);
640 return 1;
641}
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 651 of file fs_download.c.

652{
653 unsigned int i;
654
655 do
656 {
658 dr = dr->parent;
659 if (NULL == dr)
660 break;
661 for (i = 0; i < dr->num_children; i++)
662 if (dr->children[i]->state != BRS_DOWNLOAD_UP)
663 break;
664 }
665 while (i == dr->num_children);
666}

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

682{
683 uint64_t off;
684 char block[DBLOCK_SIZE];
685 struct GNUNET_HashCode key;
686 uint64_t total;
687 size_t len;
688 unsigned int i;
689 struct DownloadRequest *drc;
690 uint64_t child_block_size;
691 const struct ContentHashKey *chks;
692 int up_done;
693
694 GNUNET_assert (NULL != dc->rfh);
698 len = GNUNET_FS_tree_calculate_block_size (total, dr->offset, dr->depth);
699 GNUNET_assert (len <= DBLOCK_SIZE);
700 off = compute_disk_offset (total, dr->offset, dr->depth);
701 if (dc->old_file_size < off + len)
702 return; /* failure */
704 {
706 return; /* failure */
707 }
708 if (len != GNUNET_DISK_file_read (dc->rfh, block, len))
709 {
711 return; /* failure */
712 }
713 GNUNET_CRYPTO_hash (block, len, &key);
714 if (0 != memcmp (&key, &dr->chk.key, sizeof(struct GNUNET_HashCode)))
715 return; /* mismatch */
716 if (GNUNET_OK !=
717 encrypt_existing_match (dc, &dr->chk, dr, block, len, GNUNET_NO))
718 {
719 /* hash matches but encrypted block does not, really bad */
720 dr->state = BRS_ERROR;
721 /* propagate up */
722 while (NULL != dr->parent)
723 {
724 dr = dr->parent;
725 dr->state = BRS_ERROR;
726 }
727 return;
728 }
729 /* block matches */
731
732 /* set CHKs for children */
733 up_done = GNUNET_YES;
734 chks = (const struct ContentHashKey *) block;
735 for (i = 0; i < dr->num_children; i++)
736 {
737 drc = dr->children[i];
738 GNUNET_assert (drc->offset >= dr->offset);
739 child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth);
740 GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size);
741 if (BRS_INIT == drc->state)
742 {
743 drc->state = BRS_CHK_SET;
744 drc->chk = chks[drc->chk_idx];
746 }
747 if (BRS_DOWNLOAD_UP != drc->state)
748 up_done = GNUNET_NO; /* children not all done */
749 }
750 if (GNUNET_YES == up_done)
751 propagate_up (dr); /* children all done (or no children...) */
752}
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 764 of file fs_download.c.

765{
766 struct GNUNET_FS_DownloadContext *dc = cls;
767 struct DownloadRequest *dr = entry;
768 struct SearchMessage *sm;
769 struct GNUNET_MQ_Envelope *env;
770
774 else
776 if (0 == dr->depth)
777 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK);
778 else
779 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK);
780 sm->anonymity_level = htonl (dc->anonymity);
781 sm->target = dc->target;
782 sm->query = dr->chk.query;
784 return GNUNET_OK;
785}
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 795 of file fs_download.c.

797{
798 unsigned int i;
799
800 switch (dr->state)
801 {
802 case BRS_INIT:
803 GNUNET_assert (0);
804 break;
805
807 GNUNET_assert (0);
808 break;
809
811 GNUNET_assert (0);
812 break;
813
815 GNUNET_assert (0);
816 break;
817
818 case BRS_CHK_SET:
819 /* normal case, start download */
820 break;
821
823 for (i = 0; i < dr->num_children; i++)
825 return;
826
827 case BRS_DOWNLOAD_UP:
828 /* We're done! */
829 return;
830
831 case BRS_ERROR:
832 GNUNET_break (0);
833 return;
834 }
836 "Scheduling download at offset %llu and depth %u for `%s'\n",
837 (unsigned long long) dr->offset,
838 dr->depth,
839 GNUNET_h2s (&dr->chk.query));
841 &dr->chk.query,
842 dr))
843 return; /* already active */
845 &dr->chk.query,
846 dr,
848 if (NULL == dc->mq)
849 return; /* download not active */
850 retry_entry (dc, &dr->chk.query, dr);
851}
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 1015 of file fs_download.c.

1016{
1017 if (NULL == dr)
1018 return;
1019 for (unsigned int i = 0; i < dr->num_children; i++)
1021 GNUNET_free (dr->children);
1022 GNUNET_free (dr);
1023}

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

1317{
1318 /* any varsize length is OK */
1319 return GNUNET_OK;
1320}

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

1332{
1333 struct GNUNET_FS_DownloadContext *dc = cls;
1334 uint16_t msize = ntohs (cm->header.size) - sizeof(*cm);
1335 struct ProcessResultClosure prc;
1336
1337 prc.dc = dc;
1338 prc.data = &cm[1];
1340 prc.size = msize;
1341 prc.type = ntohl (cm->type);
1342 prc.do_store = GNUNET_YES;
1343 prc.respect_offered = ntohl (cm->respect_offered);
1344 prc.num_transmissions = ntohl (cm->num_transmissions);
1345 GNUNET_CRYPTO_hash (prc.data, msize, &prc.query);
1347 "Received result for query `%s' from FS service\n",
1348 GNUNET_h2s (&prc.query));
1350 &prc.query,
1352 &prc);
1353}
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 1365 of file fs_download.c.

1366{
1367 struct GNUNET_FS_DownloadContext *dc = cls;
1368
1369 if (NULL != dc->mq)
1370 {
1372 dc->mq = NULL;
1373 }
1375 "Transmitting download request failed, trying to reconnect\n");
1376 try_reconnect (dc);
1377}
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 1386 of file fs_download.c.

1387{
1388 struct GNUNET_FS_DownloadContext *dc = cls;
1390 { GNUNET_MQ_hd_var_size (put,
1392 struct ClientPutMessage,
1393 dc),
1395
1396 dc->task = NULL;
1398 "fs",
1399 handlers,
1401 dc);
1402 if (NULL == dc->mq)
1403 {
1405 "Connecting to `%s'-service failed, will try again.\n",
1406 "FS");
1407 try_reconnect (dc);
1408 return;
1409 }
1411}
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 1452 of file fs_download.c.

1453{
1454 struct GNUNET_FS_DownloadContext *dc = cls;
1455 struct GNUNET_FS_ProgressInfo pi;
1456
1457 GNUNET_assert (NULL == dc->mq);
1458 GNUNET_assert (NULL != dc->active);
1459 do_reconnect (dc);
1460 if (NULL != dc->mq)
1461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download activated\n");
1464}
@ 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 1473 of file fs_download.c.

1474{
1475 struct GNUNET_FS_DownloadContext *dc = cls;
1476 struct GNUNET_FS_ProgressInfo pi;
1477
1478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download deactivated\n");
1479 if (NULL != dc->mq)
1480 {
1482 dc->mq = NULL;
1483 }
1486}
@ 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 1509 of file fs_download.c.

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

1586{
1587 struct GNUNET_FS_DownloadContext *dc = cls;
1588
1589 /* clean up state from tree encoder */
1590 if (NULL != dc->task)
1591 {
1593 dc->task = NULL;
1594 }
1595 if (NULL != dc->rfh)
1596 {
1598 dc->rfh = NULL;
1599 }
1600 /* start "normal" download */
1602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting normal download\n");
1604}

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

1614{
1615 struct GNUNET_FS_DownloadContext *dc = cls;
1616
1617 dc->task = NULL;
1619}
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 1640 of file fs_download.c.

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

1793{
1794 struct GNUNET_FS_DownloadContext *dc = cls;
1795 struct GNUNET_DISK_FileHandle *fh = dc->rfh;
1796 ssize_t ret;
1797
1798 if (NULL != emsg)
1799 *emsg = NULL;
1800 if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET))
1801 {
1802 if (NULL != emsg)
1803 *emsg = GNUNET_strdup (strerror (errno));
1804 return 0;
1805 }
1806 ret = GNUNET_DISK_file_read (fh, buf, max);
1807 if (ret < 0)
1808 {
1809 if (NULL != emsg)
1810 *emsg = GNUNET_strdup (strerror (errno));
1811 return 0;
1812 }
1813 return ret;
1814}
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 1824 of file fs_download.c.

1825{
1826 struct GNUNET_FS_DownloadContext *dc = cls;
1827 struct GNUNET_FS_ProgressInfo pi;
1828 struct GNUNET_DISK_FileHandle *fh;
1829
1830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start task running...\n");
1831 dc->task = NULL;
1832 if (0 == dc->length)
1833 {
1834 /* no bytes required! */
1835 if (NULL != dc->filename)
1836 {
1840 | ((0 ==
1843 : 0),
1849 }
1852 pi.value.download.specifics.start.meta = dc->meta;
1855 return;
1856 }
1857 if (NULL != dc->emsg)
1858 return;
1859 if (NULL == dc->top_request)
1860 {
1862 0,
1863 dc->treedepth - 1,
1864 0,
1865 dc->offset,
1866 dc->length);
1869 ? dc->uri->data.chk.chk
1870 : dc->uri->data.loc.fi.chk;
1871 /* signal start */
1873 if (NULL != dc->search)
1876 pi.value.download.specifics.start.meta = dc->meta;
1878 }
1880 /* attempt reconstruction from disk */
1886 {
1887 if (NULL != dc->rfh)
1888 {
1889 /* first, try top-down */
1891 "Trying top-down reconstruction for `%s'\n",
1892 dc->filename);
1894 switch (dc->top_request->state)
1895 {
1896 case BRS_CHK_SET:
1897 break; /* normal */
1898
1899 case BRS_DOWNLOAD_DOWN:
1900 break; /* normal, some blocks already down */
1901
1902 case BRS_DOWNLOAD_UP:
1903 /* already done entirely, party! */
1904 if (NULL != dc->rfh)
1905 {
1906 /* avoid hanging on to file handle longer than
1907 * necessary */
1909 dc->rfh = NULL;
1910 }
1911 return;
1912
1913 case BRS_ERROR:
1914 GNUNET_asprintf (&dc->emsg, _ ("Invalid URI"));
1917 pi.value.download.specifics.error.message = dc->emsg;
1919 return;
1920
1921 default:
1922 GNUNET_assert (0);
1923 break;
1924 }
1925 }
1926 }
1927 /* attempt reconstruction from meta data */
1929 (NULL != dc->meta))
1930 {
1931 GNUNET_log (
1933 "Trying to find embedded meta data for download of size %llu with %u bytes MD\n",
1934 (unsigned long long) GNUNET_FS_uri_chk_get_file_size (dc->uri),
1938 {
1939 if (NULL != dc->rfh)
1940 {
1941 /* avoid hanging on to file handle longer than
1942 * necessary */
1944 dc->rfh = NULL;
1945 }
1946 return; /* finished, status update was already done for us */
1947 }
1948 }
1949 if (NULL != dc->rfh)
1950 {
1951 /* finally, actually run bottom-up */
1953 "Trying bottom-up reconstruction of file `%s'\n",
1954 dc->filename);
1955 dc->te =
1958 dc,
1959 &fh_reader,
1961 NULL,
1964 }
1965 else
1966 {
1967 /* simple, top-level download */
1970 }
1973}
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 1977 of file fs_download.c.

1978{
1979 struct GNUNET_FS_DownloadContext *dc = cls;
1980 struct GNUNET_FS_ProgressInfo pi;
1981
1982 if (NULL != dc->top)
1984 while (NULL != dc->child_head)
1986 if (NULL != dc->search)
1987 {
1988 dc->search->download = NULL;
1989 dc->search = NULL;
1990 }
1991 if (NULL != dc->job_queue)
1992 {
1994 dc->job_queue = NULL;
1995 }
1996 if (NULL != dc->parent)
1999 dc);
2000 if (NULL != dc->task)
2001 {
2003 dc->task = NULL;
2004 }
2007 if (NULL != dc->te)
2008 {
2010 dc->te = NULL;
2011 }
2012 if (NULL != dc->rfh)
2013 {
2015 dc->rfh = NULL;
2016 }
2018 if (NULL != dc->active)
2019 {
2021 dc->active = NULL;
2022 }
2028 GNUNET_assert (NULL == dc->job_queue);
2029 GNUNET_free (dc);
2030}
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:445
#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 2053 of file fs_download.c.

2063{
2065
2067 if ((offset + length < offset) ||
2069 {
2070 GNUNET_break (0);
2071 return NULL;
2072 }
2075 "Starting download %p, %u bytes at offset %llu\n",
2076 dc,
2077 (unsigned int) length,
2078 (unsigned long long) offset);
2079 dc->h = h;
2082 dc->client_info = cctx;
2084 if (NULL != filename)
2085 {
2089 &dc->old_file_size,
2090 GNUNET_YES,
2091 GNUNET_YES));
2092 }
2096 dc->offset = offset;
2097 dc->length = length;
2099 dc->options = options;
2100 dc->active =
2102 GNUNET_NO);
2103 dc->treedepth =
2105 if ((NULL == filename) && (is_recursive_download (dc)))
2106 {
2107 if (NULL != tempname)
2108 dc->temp_filename = GNUNET_strdup (tempname);
2109 else
2110 dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp");
2111 }
2113 "Starting download `%s' of %llu bytes with tree depth %u\n",
2114 filename,
2115 (unsigned long long) length,
2116 dc->treedepth);
2117 GNUNET_assert (NULL == dc->job_queue);
2119 return dc;
2120}
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 2208 of file fs_download.c.

2209{
2210 if (dc->completed == dc->length)
2211 return;
2212 if (NULL != dc->mq)
2213 return; /* already running */
2214 GNUNET_assert (NULL == dc->job_queue);
2215 GNUNET_assert (NULL == dc->task);
2216 GNUNET_assert (NULL != dc->active);
2217 dc->job_queue =
2221 dc,
2222 (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE,
2227 "Download %p put into queue as job %p\n",
2228 dc,
2229 dc->job_queue);
2230}
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: