aboutsummaryrefslogtreecommitdiff
path: root/src/fs
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-08 09:23:47 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-08 09:23:47 +0000
commit539be627c009c2f13da19d6ae847168c1f5d496e (patch)
tree78814fdb491c52349f793af5898858a56e32117a /src/fs
parent941c7ee262792114da1811cf4404b04550e071b1 (diff)
downloadgnunet-539be627c009c2f13da19d6ae847168c1f5d496e.tar.gz
gnunet-539be627c009c2f13da19d6ae847168c1f5d496e.zip
-LRN: my experimental block download time measurer. The results
can be found there - [1]. [1] http://lrn.no-ip.info/other/gnunet_download_tie.log
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/fs.h36
-rw-r--r--src/fs/fs_api.h1
-rw-r--r--src/fs/fs_download.c27
-rw-r--r--src/fs/fs_search.c8
-rw-r--r--src/fs/gnunet-download.c13
-rw-r--r--src/fs/gnunet-service-fs_cp.c1
-rw-r--r--src/fs/gnunet-service-fs_lc.c9
-rw-r--r--src/fs/gnunet-service-fs_pe.c25
-rw-r--r--src/fs/gnunet-service-fs_pe.h13
-rw-r--r--src/fs/gnunet-service-fs_pr.c14
-rw-r--r--src/fs/gnunet-service-fs_pr.h3
11 files changed, 127 insertions, 23 deletions
diff --git a/src/fs/fs.h b/src/fs/fs.h
index cd39522bc..059b8920d 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -267,7 +267,7 @@ struct SearchMessage
267 * Response from FS service with a result for a previous FS search. 267 * Response from FS service with a result for a previous FS search.
268 * Note that queries for DBLOCKS and IBLOCKS that have received a 268 * Note that queries for DBLOCKS and IBLOCKS that have received a
269 * single response are considered done. This message is transmitted 269 * single response are considered done. This message is transmitted
270 * between peers as well as between the service and a client. 270 * between peers.
271 */ 271 */
272struct PutMessage 272struct PutMessage
273{ 273{
@@ -290,6 +290,40 @@ struct PutMessage
290 /* this is followed by the actual encrypted content */ 290 /* this is followed by the actual encrypted content */
291 291
292}; 292};
293
294/**
295 * Response from FS service with a result for a previous FS search.
296 * Note that queries for DBLOCKS and IBLOCKS that have received a
297 * single response are considered done. This message is transmitted
298 * between the service and a client.
299 */
300struct ClientPutMessage
301{
302
303 /**
304 * Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
305 */
306 struct GNUNET_MessageHeader header;
307
308 /**
309 * Type of the block (in big endian). Should never be zero.
310 */
311 uint32_t type GNUNET_PACKED;
312
313 /**
314 * When does this result expire?
315 */
316 struct GNUNET_TIME_AbsoluteNBO expiration;
317
318 /**
319 * When was the last time we've tried to download this block?
320 * (FOREVER if unknown/not relevant)
321 */
322 struct GNUNET_TIME_AbsoluteNBO last_transmission;
323
324 /* this is followed by the actual encrypted content */
325
326};
293GNUNET_NETWORK_STRUCT_END 327GNUNET_NETWORK_STRUCT_END
294 328
295 329
diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h
index 66ccda1f2..4f3781d01 100644
--- a/src/fs/fs_api.h
+++ b/src/fs/fs_api.h
@@ -1906,7 +1906,6 @@ struct GNUNET_FS_Namespace
1906 unsigned int nug_gen; 1906 unsigned int nug_gen;
1907}; 1907};
1908 1908
1909
1910#endif 1909#endif
1911 1910
1912/* end of fs_api.h */ 1911/* end of fs_api.h */
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index cc36cba1f..85ae3ae34 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -118,6 +118,7 @@ GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
118 pi->value.download.uri = dc->uri; 118 pi->value.download.uri = dc->uri;
119 pi->value.download.filename = dc->filename; 119 pi->value.download.filename = dc->filename;
120 pi->value.download.size = dc->length; 120 pi->value.download.size = dc->length;
121 /* FIXME: Fix duration calculation to account for pauses */
121 pi->value.download.duration = 122 pi->value.download.duration =
122 GNUNET_TIME_absolute_get_duration (dc->start_time); 123 GNUNET_TIME_absolute_get_duration (dc->start_time);
123 pi->value.download.completed = dc->completed; 124 pi->value.download.completed = dc->completed;
@@ -183,6 +184,8 @@ struct ProcessResultClosure
183 */ 184 */
184 int do_store; 185 int do_store;
185 186
187 struct GNUNET_TIME_Absolute last_transmission;
188
186}; 189};
187 190
188 191
@@ -251,6 +254,7 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc,
251 dr->depth) ? GNUNET_BLOCK_TYPE_FS_DBLOCK : GNUNET_BLOCK_TYPE_FS_IBLOCK; 254 dr->depth) ? GNUNET_BLOCK_TYPE_FS_DBLOCK : GNUNET_BLOCK_TYPE_FS_IBLOCK;
252 prc.query = chk->query; 255 prc.query = chk->query;
253 prc.do_store = do_store; 256 prc.do_store = do_store;
257 prc.last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
254 process_result_with_request (&prc, &chk->key, dr); 258 process_result_with_request (&prc, &chk->key, dr);
255 return GNUNET_OK; 259 return GNUNET_OK;
256} 260}
@@ -1072,6 +1076,12 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
1072 pi.value.download.specifics.progress.data_len = prc->size; 1076 pi.value.download.specifics.progress.data_len = prc->size;
1073 pi.value.download.specifics.progress.depth = dr->depth; 1077 pi.value.download.specifics.progress.depth = dr->depth;
1074 pi.value.download.specifics.progress.trust_offered = 0; 1078 pi.value.download.specifics.progress.trust_offered = 0;
1079 if (prc->last_transmission.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
1080 pi.value.download.specifics.progress.block_download_duration =
1081 GNUNET_TIME_absolute_get_duration (prc->last_transmission);
1082 else
1083 pi.value.download.specifics.progress.block_download_duration.rel_value =
1084 GNUNET_TIME_UNIT_FOREVER_REL.rel_value;
1075 GNUNET_FS_download_make_status_ (&pi, dc); 1085 GNUNET_FS_download_make_status_ (&pi, dc);
1076 GNUNET_assert (dc->completed <= dc->length); 1086 GNUNET_assert (dc->completed <= dc->length);
1077 if (dr->depth == 0) 1087 if (dr->depth == 0)
@@ -1182,12 +1192,15 @@ signal_error:
1182 * 1192 *
1183 * @param dc our download context 1193 * @param dc our download context
1184 * @param type type of the result 1194 * @param type type of the result
1195 * @param last_transmission when was this block requested the last time? (FOREVER if unknown/not applicable)
1185 * @param data the (encrypted) response 1196 * @param data the (encrypted) response
1186 * @param size size of data 1197 * @param size size of data
1187 */ 1198 */
1188static void 1199static void
1189process_result (struct GNUNET_FS_DownloadContext *dc, 1200process_result (struct GNUNET_FS_DownloadContext *dc,
1190 enum GNUNET_BLOCK_Type type, const void *data, size_t size) 1201 enum GNUNET_BLOCK_Type type,
1202 struct GNUNET_TIME_Absolute last_transmission,
1203 const void *data, size_t size)
1191{ 1204{
1192 struct ProcessResultClosure prc; 1205 struct ProcessResultClosure prc;
1193 1206
@@ -1196,6 +1209,7 @@ process_result (struct GNUNET_FS_DownloadContext *dc,
1196 prc.size = size; 1209 prc.size = size;
1197 prc.type = type; 1210 prc.type = type;
1198 prc.do_store = GNUNET_YES; 1211 prc.do_store = GNUNET_YES;
1212 prc.last_transmission = last_transmission;
1199 GNUNET_CRYPTO_hash (data, size, &prc.query); 1213 GNUNET_CRYPTO_hash (data, size, &prc.query);
1200#if DEBUG_DOWNLOAD 1214#if DEBUG_DOWNLOAD
1201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1219,20 +1233,21 @@ static void
1219receive_results (void *cls, const struct GNUNET_MessageHeader *msg) 1233receive_results (void *cls, const struct GNUNET_MessageHeader *msg)
1220{ 1234{
1221 struct GNUNET_FS_DownloadContext *dc = cls; 1235 struct GNUNET_FS_DownloadContext *dc = cls;
1222 const struct PutMessage *cm; 1236 const struct ClientPutMessage *cm;
1223 uint16_t msize; 1237 uint16_t msize;
1224 1238
1225 if ((NULL == msg) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) || 1239 if ((NULL == msg) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) ||
1226 (sizeof (struct PutMessage) > ntohs (msg->size))) 1240 (sizeof (struct ClientPutMessage) > ntohs (msg->size)))
1227 { 1241 {
1228 GNUNET_break (msg == NULL); 1242 GNUNET_break (msg == NULL);
1229 try_reconnect (dc); 1243 try_reconnect (dc);
1230 return; 1244 return;
1231 } 1245 }
1232 msize = ntohs (msg->size); 1246 msize = ntohs (msg->size);
1233 cm = (const struct PutMessage *) msg; 1247 cm = (const struct ClientPutMessage *) msg;
1234 process_result (dc, ntohl (cm->type), &cm[1], 1248 process_result (dc, ntohl (cm->type),
1235 msize - sizeof (struct PutMessage)); 1249 GNUNET_TIME_absolute_ntoh (cm->last_transmission), &cm[1],
1250 msize - sizeof (struct ClientPutMessage));
1236 if (dc->client == NULL) 1251 if (dc->client == NULL)
1237 return; /* fatal error */ 1252 return; /* fatal error */
1238 /* continue receiving */ 1253 /* continue receiving */
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 55db586b0..03b4a7dfd 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -835,11 +835,11 @@ static void
835receive_results (void *cls, const struct GNUNET_MessageHeader *msg) 835receive_results (void *cls, const struct GNUNET_MessageHeader *msg)
836{ 836{
837 struct GNUNET_FS_SearchContext *sc = cls; 837 struct GNUNET_FS_SearchContext *sc = cls;
838 const struct PutMessage *cm; 838 const struct ClientPutMessage *cm;
839 uint16_t msize; 839 uint16_t msize;
840 840
841 if ((NULL == msg) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) || 841 if ((NULL == msg) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) ||
842 (ntohs (msg->size) <= sizeof (struct PutMessage))) 842 (ntohs (msg->size) <= sizeof (struct ClientPutMessage)))
843 { 843 {
844 try_reconnect (sc); 844 try_reconnect (sc);
845 return; 845 return;
@@ -847,10 +847,10 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg)
847 msize = ntohs (msg->size); 847 msize = ntohs (msg->size);
848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
849 "Receiving %u bytes of result from fs service\n", msize); 849 "Receiving %u bytes of result from fs service\n", msize);
850 cm = (const struct PutMessage *) msg; 850 cm = (const struct ClientPutMessage *) msg;
851 process_result (sc, ntohl (cm->type), 851 process_result (sc, ntohl (cm->type),
852 GNUNET_TIME_absolute_ntoh (cm->expiration), &cm[1], 852 GNUNET_TIME_absolute_ntoh (cm->expiration), &cm[1],
853 msize - sizeof (struct PutMessage)); 853 msize - sizeof (struct ClientPutMessage));
854 /* continue receiving */ 854 /* continue receiving */
855 GNUNET_CLIENT_receive (sc->client, &receive_results, sc, 855 GNUNET_CLIENT_receive (sc->client, &receive_results, sc,
856 GNUNET_TIME_UNIT_FOREVER_REL); 856 GNUNET_TIME_UNIT_FOREVER_REL);
diff --git a/src/fs/gnunet-download.c b/src/fs/gnunet-download.c
index b6c67ce27..ff10c39c6 100644
--- a/src/fs/gnunet-download.c
+++ b/src/fs/gnunet-download.c
@@ -90,7 +90,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
90static void * 90static void *
91progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) 91progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
92{ 92{
93 char *s; 93 char *s, *s2;
94 char *t; 94 char *t;
95 95
96 switch (info->status) 96 switch (info->status)
@@ -104,16 +104,23 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
104 if (verbose) 104 if (verbose)
105 { 105 {
106 s = GNUNET_STRINGS_relative_time_to_string (info->value.download.eta); 106 s = GNUNET_STRINGS_relative_time_to_string (info->value.download.eta);
107 if (info->value.download.specifics.progress.block_download_duration.rel_value
108 == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
109 s2 = GNUNET_strdup (_("<unknown time>"));
110 else
111 s2 = GNUNET_STRINGS_relative_time_to_string (
112 info->value.download.specifics.progress.block_download_duration);
107 t = GNUNET_STRINGS_byte_size_fancy (info->value.download.completed * 113 t = GNUNET_STRINGS_byte_size_fancy (info->value.download.completed *
108 1000LL / 114 1000LL /
109 (info->value.download. 115 (info->value.download.
110 duration.rel_value + 1)); 116 duration.rel_value + 1));
111 FPRINTF (stdout, 117 FPRINTF (stdout,
112 _("Downloading `%s' at %llu/%llu (%s remaining, %s/s)\n"), 118 _("Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to download\n"),
113 info->value.download.filename, 119 info->value.download.filename,
114 (unsigned long long) info->value.download.completed, 120 (unsigned long long) info->value.download.completed,
115 (unsigned long long) info->value.download.size, s, t); 121 (unsigned long long) info->value.download.size, s, t, s2);
116 GNUNET_free (s); 122 GNUNET_free (s);
123 GNUNET_free (s2);
117 GNUNET_free (t); 124 GNUNET_free (t);
118 } 125 }
119 break; 126 break;
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c
index 4711c09e6..ba6a8ce87 100644
--- a/src/fs/gnunet-service-fs_cp.c
+++ b/src/fs/gnunet-service-fs_cp.c
@@ -883,6 +883,7 @@ static void
883handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, 883handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval,
884 struct GSF_PendingRequest *pr, uint32_t reply_anonymity_level, 884 struct GSF_PendingRequest *pr, uint32_t reply_anonymity_level,
885 struct GNUNET_TIME_Absolute expiration, 885 struct GNUNET_TIME_Absolute expiration,
886 struct GNUNET_TIME_Absolute last_transmission,
886 enum GNUNET_BLOCK_Type type, const void *data, 887 enum GNUNET_BLOCK_Type type, const void *data,
887 size_t data_len) 888 size_t data_len)
888{ 889{
diff --git a/src/fs/gnunet-service-fs_lc.c b/src/fs/gnunet-service-fs_lc.c
index d8f7d5cb3..6eb054acd 100644
--- a/src/fs/gnunet-service-fs_lc.c
+++ b/src/fs/gnunet-service-fs_lc.c
@@ -218,6 +218,7 @@ client_request_destroy (void *cls,
218 * @param pr handle to the original pending request 218 * @param pr handle to the original pending request
219 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown" 219 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown"
220 * @param expiration when does 'data' expire? 220 * @param expiration when does 'data' expire?
221 * @param last_transmission when was the last time we've tried to download this block? (FOREVER if unknown)
221 * @param type type of the block 222 * @param type type of the block
222 * @param data response data, NULL on request expiration 223 * @param data response data, NULL on request expiration
223 * @param data_len number of bytes in data 224 * @param data_len number of bytes in data
@@ -227,12 +228,13 @@ client_response_handler (void *cls, enum GNUNET_BLOCK_EvaluationResult eval,
227 struct GSF_PendingRequest *pr, 228 struct GSF_PendingRequest *pr,
228 uint32_t reply_anonymity_level, 229 uint32_t reply_anonymity_level,
229 struct GNUNET_TIME_Absolute expiration, 230 struct GNUNET_TIME_Absolute expiration,
231 struct GNUNET_TIME_Absolute last_transmission,
230 enum GNUNET_BLOCK_Type type, const void *data, 232 enum GNUNET_BLOCK_Type type, const void *data,
231 size_t data_len) 233 size_t data_len)
232{ 234{
233 struct ClientRequest *cr = cls; 235 struct ClientRequest *cr = cls;
234 struct GSF_LocalClient *lc; 236 struct GSF_LocalClient *lc;
235 struct PutMessage *pm; 237 struct ClientPutMessage *pm;
236 const struct GSF_PendingRequestData *prd; 238 const struct GSF_PendingRequestData *prd;
237 size_t msize; 239 size_t msize;
238 240
@@ -255,15 +257,16 @@ client_response_handler (void *cls, enum GNUNET_BLOCK_EvaluationResult eval,
255 GNUNET_NO); 257 GNUNET_NO);
256 GNUNET_assert (pr == cr->pr); 258 GNUNET_assert (pr == cr->pr);
257 lc = cr->lc; 259 lc = cr->lc;
258 msize = sizeof (struct PutMessage) + data_len; 260 msize = sizeof (struct ClientPutMessage) + data_len;
259 { 261 {
260 char buf[msize]; 262 char buf[msize];
261 263
262 pm = (struct PutMessage *) buf; 264 pm = (struct ClientPutMessage *) buf;
263 pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT); 265 pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT);
264 pm->header.size = htons (msize); 266 pm->header.size = htons (msize);
265 pm->type = htonl (type); 267 pm->type = htonl (type);
266 pm->expiration = GNUNET_TIME_absolute_hton (expiration); 268 pm->expiration = GNUNET_TIME_absolute_hton (expiration);
269 pm->last_transmission = GNUNET_TIME_absolute_hton (last_transmission);
267 memcpy (&pm[1], data, data_len); 270 memcpy (&pm[1], data, data_len);
268 GSF_local_client_transmit_ (lc, &pm->header); 271 GSF_local_client_transmit_ (lc, &pm->header);
269 } 272 }
diff --git a/src/fs/gnunet-service-fs_pe.c b/src/fs/gnunet-service-fs_pe.c
index 0a40065cc..78769fa82 100644
--- a/src/fs/gnunet-service-fs_pe.c
+++ b/src/fs/gnunet-service-fs_pe.c
@@ -699,6 +699,31 @@ GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp)
699 GNUNET_free (pp); 699 GNUNET_free (pp);
700} 700}
701 701
702/**
703 * Get the last transmission attempt time for the request plan list
704 * referenced by @rpr_head, that was sent to @sender
705 *
706 * @param rpr_head request plan reference list to check.
707 * @param sender the peer that we've sent the request to.
708 * @param result the timestamp to fill.
709 * @return GNUNET_YES if @result was changed, GNUNET_NO otherwise.
710 */
711int
712GSF_request_plan_reference_get_last_transmission_ (
713 struct GSF_RequestPlanReference *rpr_head, struct GSF_ConnectedPeer *sender,
714 struct GNUNET_TIME_Absolute *result)
715{
716 struct GSF_RequestPlanReference *rpr;
717 for (rpr = rpr_head; rpr; rpr = rpr->next)
718 {
719 if (rpr->rp->pp->cp == sender)
720 {
721 *result = rpr->rp->last_transmission;
722 return GNUNET_YES;
723 }
724 }
725 return GNUNET_NO;
726}
702 727
703/** 728/**
704 * Notify the plan about a request being done; destroy all entries 729 * Notify the plan about a request being done; destroy all entries
diff --git a/src/fs/gnunet-service-fs_pe.h b/src/fs/gnunet-service-fs_pe.h
index 3ae9904a6..da20a7d7b 100644
--- a/src/fs/gnunet-service-fs_pe.h
+++ b/src/fs/gnunet-service-fs_pe.h
@@ -58,6 +58,19 @@ GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp);
58void 58void
59GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr); 59GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr);
60 60
61/**
62 * Get the last transmission attempt time for the request plan list
63 * referenced by @rpr_head, that was sent to @sender
64 *
65 * @param rpr_head request plan reference list to check.
66 * @param sender the peer that we've sent the request to.
67 * @param result the timestamp to fill.
68 * @return GNUNET_YES if @result was changed, GNUNET_NO otherwise.
69 */
70int
71GSF_request_plan_reference_get_last_transmission_ (
72 struct GSF_RequestPlanReference *rpr_head, struct GSF_ConnectedPeer *sender,
73 struct GNUNET_TIME_Absolute *result);
61 74
62/** 75/**
63 * Initialize plan subsystem. 76 * Initialize plan subsystem.
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c
index 5ba58c4b8..c16f94464 100644
--- a/src/fs/gnunet-service-fs_pr.c
+++ b/src/fs/gnunet-service-fs_pr.c
@@ -360,8 +360,8 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options,
360 break; /* let the request live briefly... */ 360 break; /* let the request live briefly... */
361 if (NULL != dpr->rh) 361 if (NULL != dpr->rh)
362 dpr->rh (dpr->rh_cls, GNUNET_BLOCK_EVALUATION_REQUEST_VALID, dpr, 362 dpr->rh (dpr->rh_cls, GNUNET_BLOCK_EVALUATION_REQUEST_VALID, dpr,
363 UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_BLOCK_TYPE_ANY, 363 UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_ABS,
364 NULL, 0); 364 GNUNET_BLOCK_TYPE_ANY, NULL, 0);
365 GSF_pending_request_cancel_ (dpr, GNUNET_YES); 365 GSF_pending_request_cancel_ (dpr, GNUNET_YES);
366 } 366 }
367 } 367 }
@@ -371,7 +371,6 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options,
371 return pr; 371 return pr;
372} 372}
373 373
374
375/** 374/**
376 * Obtain the public data associated with a pending request 375 * Obtain the public data associated with a pending request
377 * 376 *
@@ -775,6 +774,7 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value)
775 struct ProcessReplyClosure *prq = cls; 774 struct ProcessReplyClosure *prq = cls;
776 struct GSF_PendingRequest *pr = value; 775 struct GSF_PendingRequest *pr = value;
777 GNUNET_HashCode chash; 776 GNUNET_HashCode chash;
777 struct GNUNET_TIME_Absolute last_transmission;
778 778
779 if (NULL == pr->rh) 779 if (NULL == pr->rh)
780 return GNUNET_YES; 780 return GNUNET_YES;
@@ -804,9 +804,11 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value)
804 GNUNET_LOAD_update (GSF_rt_entry_lifetime, 804 GNUNET_LOAD_update (GSF_rt_entry_lifetime,
805 GNUNET_TIME_absolute_get_duration (pr-> 805 GNUNET_TIME_absolute_get_duration (pr->
806 public_data.start_time).rel_value); 806 public_data.start_time).rel_value);
807 if (!GSF_request_plan_reference_get_last_transmission_ (pr->public_data.rpr_head, prq->sender, &last_transmission))
808 last_transmission.abs_value = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value;
807 /* pass on to other peers / local clients */ 809 /* pass on to other peers / local clients */
808 pr->rh (pr->rh_cls, prq->eval, pr, prq->anonymity_level, prq->expiration, 810 pr->rh (pr->rh_cls, prq->eval, pr, prq->anonymity_level, prq->expiration,
809 prq->type, prq->data, prq->size); 811 last_transmission, prq->type, prq->data, prq->size);
810 return GNUNET_YES; 812 return GNUNET_YES;
811 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: 813 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
812 GNUNET_STATISTICS_update (GSF_stats, 814 GNUNET_STATISTICS_update (GSF_stats,
@@ -855,8 +857,10 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value)
855 pr->public_data.results_found++; 857 pr->public_data.results_found++;
856 prq->request_found = GNUNET_YES; 858 prq->request_found = GNUNET_YES;
857 /* finally, pass on to other peer / local client */ 859 /* finally, pass on to other peer / local client */
860 if (!GSF_request_plan_reference_get_last_transmission_ (pr->public_data.rpr_head, prq->sender, &last_transmission))
861 last_transmission.abs_value = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value;
858 pr->rh (pr->rh_cls, prq->eval, pr, prq->anonymity_level, prq->expiration, 862 pr->rh (pr->rh_cls, prq->eval, pr, prq->anonymity_level, prq->expiration,
859 prq->type, prq->data, prq->size); 863 last_transmission, prq->type, prq->data, prq->size);
860 return GNUNET_YES; 864 return GNUNET_YES;
861} 865}
862 866
diff --git a/src/fs/gnunet-service-fs_pr.h b/src/fs/gnunet-service-fs_pr.h
index f435cf8d6..92827f76b 100644
--- a/src/fs/gnunet-service-fs_pr.h
+++ b/src/fs/gnunet-service-fs_pr.h
@@ -174,6 +174,7 @@ struct GSF_PendingRequestData
174 * @param pr handle to the original pending request 174 * @param pr handle to the original pending request
175 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown" 175 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown"
176 * @param expiration when does 'data' expire? 176 * @param expiration when does 'data' expire?
177 * @param last_transmission the last time we've tried to get this block (FOREVER if unknown)
177 * @param type type of the block 178 * @param type type of the block
178 * @param data response data, NULL on request expiration 179 * @param data response data, NULL on request expiration
179 * @param data_len number of bytes in data 180 * @param data_len number of bytes in data
@@ -186,6 +187,8 @@ typedef void (*GSF_PendingRequestReplyHandler) (void *cls,
186 uint32_t reply_anonymity_level, 187 uint32_t reply_anonymity_level,
187 struct GNUNET_TIME_Absolute 188 struct GNUNET_TIME_Absolute
188 expiration, 189 expiration,
190 struct GNUNET_TIME_Absolute
191 last_transmission,
189 enum GNUNET_BLOCK_Type type, 192 enum GNUNET_BLOCK_Type type,
190 const void *data, 193 const void *data,
191 size_t data_len); 194 size_t data_len);