From 2ca3d0343fdda87012cedd096d891627b3c59cb2 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 19 Oct 2009 21:58:41 +0000 Subject: [PATCH] fixing bugs, diagnosis summary --- src/fs/fs.h | 6 +++ src/fs/fs_download.c | 101 +++++++++++++++++++++++++++++-------- src/fs/gnunet-service-fs.c | 15 ++++-- 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/fs/fs.h b/src/fs/fs.h index f335888ef..6c474369e 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -951,6 +951,12 @@ struct GNUNET_FS_DownloadContext */ struct GNUNET_DISK_FileHandle *handle; + /** + * Non-NULL if we are currently having a request for + * transmission pending with the client handle. + */ + struct GNUNET_CONNECTION_TransmitHandle *th; + /** * Identity of the peer having the content, or all-zeros * if we don't know of such a peer. diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index e6342a067..defc9724f 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -120,7 +120,7 @@ compute_dblock_offset (uint64_t offset, lsize = DBLOCK_SIZE; for (i=treedepth-1;i>depth;i--) lsize *= CHK_PER_INODE; - return offset + i * lsize; + return offset + k * lsize; } @@ -154,6 +154,22 @@ make_download_status (struct GNUNET_FS_ProgressInfo *pi, = dc->anonymity; } +/** + * We're ready to transmit a search request to the + * file-sharing service. Do it. If there is + * more than one request pending, try to send + * multiple or request another transmission. + * + * @param cls closure + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_download_request (void *cls, + size_t size, + void *buf); + /** * Schedule the download of the specified @@ -217,6 +233,15 @@ schedule_block_download (struct GNUNET_FS_DownloadContext *dc, &chk->query, sm, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + + if ( (dc->th == NULL) && + (dc->client != NULL) ) + dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, + sizeof (struct SearchMessage), + GNUNET_CONSTANTS_SERVICE_TIMEOUT, + &transmit_download_request, + dc); + } @@ -298,7 +323,7 @@ process_result (struct GNUNET_FS_DownloadContext *dc, char pt[size]; uint64_t off; size_t app; - unsigned int i; + int i; struct ContentHashKey *chk; char *emsg; @@ -310,11 +335,16 @@ process_result (struct GNUNET_FS_DownloadContext *dc, GNUNET_h2s (&query), "FS"); #endif - sm = GNUNET_CONTAINER_multihashmap_get (dc->active, + sm = GNUNET_CONTAINER_multihashmap_get (dc->active, &query); if (NULL == sm) { - GNUNET_break (0); + GNUNET_break (0); /* FIXME: this assertion actually fails for one + of my tests, the ascii-strings of the + query match what was printed when the + request was originally made; this does + NOT happen if in line ~825 a HT size + of 1 is used! => bug in HT? */ return; } if (size != calculate_block_size (GNUNET_ntohll (dc->uri->data.chk.file_length), @@ -323,8 +353,13 @@ process_result (struct GNUNET_FS_DownloadContext *dc, sm->depth)) { #if DEBUG_DOWNLOAD - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Internal error or bogus download URI\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Internal error or bogus download URI (expected %u bytes, got %u)\n", + calculate_block_size (GNUNET_ntohll (dc->uri->data.chk.file_length), + dc->treedepth, + sm->offset, + sm->depth), + size); #endif dc->emsg = GNUNET_strdup ("Internal error or bogus download URI"); /* signal error */ @@ -334,6 +369,11 @@ process_result (struct GNUNET_FS_DownloadContext *dc, dc->client_info = dc->h->upcb (dc->h->upcb_cls, &pi); /* abort all pending requests */ + if (NULL != dc->th) + { + GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); + dc->th = NULL; + } GNUNET_CLIENT_disconnect (dc->client); dc->client = NULL; return; @@ -395,6 +435,11 @@ process_result (struct GNUNET_FS_DownloadContext *dc, &pi); /* abort all pending requests */ + if (NULL != dc->th) + { + GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); + dc->th = NULL; + } GNUNET_CLIENT_disconnect (dc->client); dc->client = NULL; return; @@ -459,12 +504,13 @@ process_result (struct GNUNET_FS_DownloadContext *dc, return; #if DEBUG_DOWNLOAD GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Triggering downloads of children (this block was at level %u)\n", - dc->treedepth); + "Triggering downloads of children (this block was at level %u and offset %llu)\n", + sm->depth, + (unsigned long long) sm->offset); #endif GNUNET_assert (0 == (size % sizeof(struct ContentHashKey))); chk = (struct ContentHashKey*) pt; - for (i=0;i<(size / sizeof(struct ContentHashKey));i++) + for (i=(size / sizeof(struct ContentHashKey))-1;i>=0;i--) { off = compute_dblock_offset (sm->offset, sm->depth, @@ -508,6 +554,8 @@ receive_results (void *cls, ntohl (cm->type), &cm[1], msize - sizeof (struct ContentMessage)); + if (dc->client == NULL) + return; /* fatal error */ /* continue receiving */ GNUNET_CLIENT_receive (dc->client, &receive_results, @@ -537,6 +585,7 @@ transmit_download_request (void *cls, size_t msize; struct SearchMessage *sm; + dc->th = NULL; if (NULL == buf) { try_reconnect (dc); @@ -565,6 +614,12 @@ transmit_download_request (void *cls, msize += sizeof (struct SearchMessage); sm++; } + if (dc->pending != NULL) + dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, + sizeof (struct SearchMessage), + GNUNET_CONSTANTS_SERVICE_TIMEOUT, + &transmit_download_request, + dc); return msize; } @@ -596,11 +651,11 @@ do_reconnect (void *cls, return; } dc->client = client; - GNUNET_CLIENT_notify_transmit_ready (client, - sizeof (struct SearchMessage), - GNUNET_CONSTANTS_SERVICE_TIMEOUT, - &transmit_download_request, - dc); + dc->th = GNUNET_CLIENT_notify_transmit_ready (client, + sizeof (struct SearchMessage), + GNUNET_CONSTANTS_SERVICE_TIMEOUT, + &transmit_download_request, + dc); GNUNET_CLIENT_receive (client, &receive_results, dc, @@ -647,6 +702,11 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc) if (NULL != dc->client) { + if (NULL != dc->th) + { + GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); + dc->th = NULL; + } GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc); @@ -762,6 +822,7 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, dc->length = length; dc->anonymity = anonymity; dc->options = options; + // dc->active = GNUNET_CONTAINER_multihashmap_create (1); // + (length / DBLOCK_SIZE)); dc->active = GNUNET_CONTAINER_multihashmap_create (1 + (length / DBLOCK_SIZE)); dc->treedepth = GNUNET_FS_compute_depth (GNUNET_ntohll(dc->uri->data.chk.file_length)); #if DEBUG_DOWNLOAD @@ -773,12 +834,7 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, schedule_block_download (dc, &dc->uri->data.chk.chk, 0, - 0); - GNUNET_CLIENT_notify_transmit_ready (client, - sizeof (struct SearchMessage), - GNUNET_CONSTANTS_SERVICE_TIMEOUT, - &transmit_download_request, - dc); + 1 /* 0 == CHK, 1 == top */); GNUNET_CLIENT_receive (client, &receive_results, dc, @@ -832,6 +888,11 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, if (GNUNET_SCHEDULER_NO_TASK != dc->task) GNUNET_SCHEDULER_cancel (dc->h->sched, dc->task); + if (NULL != dc->th) + { + GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); + dc->th = NULL; + } if (NULL != dc->client) GNUNET_CLIENT_disconnect (dc->client); GNUNET_CONTAINER_multihashmap_iterate (dc->active, diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index ac2f9f408..639780fc2 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c @@ -47,6 +47,8 @@ #include "gnunet_util_lib.h" #include "fs.h" +#define DEBUG_FS GNUNET_YES + /** * In-memory information about indexed files (also available @@ -2000,7 +2002,8 @@ process_local_get_result (void *cls, lgc); return; } - if (type != lgc->type) + if ( (type != lgc->type) && + (lgc->type != GNUNET_DATASTORE_BLOCKTYPE_ANY) ) { /* this should be virtually impossible to reach (DBLOCK query hash being identical to KBLOCK/SBLOCK query hash); @@ -2008,7 +2011,9 @@ process_local_get_result (void *cls, simply skip the result. */ #if DEBUG_FS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received block of unexpected type for `%s' from local datastore, ignoring.\n", + "Received block of unexpected type (%u, want %u) for `%s' from local datastore, ignoring.\n", + type, + lgc->type, GNUNET_h2s (&lgc->query)); #endif GNUNET_DATASTORE_get_next (dsh, GNUNET_YES); @@ -2829,7 +2834,7 @@ handle_p2p_get (void *cls, #if DEBUG_FS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dropping query from `%s', this peer is too busy.\n", - GNUNET_h2s (other)); + GNUNET_i2s (other)); #endif return GNUNET_OK; } @@ -2866,7 +2871,7 @@ handle_p2p_get (void *cls, #if DEBUG_FS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dropping query from `%s', network saturated.\n", - GNUNET_h2s (other)); + GNUNET_i2s (other)); #endif if (NULL != pgc->bf) GNUNET_CONTAINER_bloomfilter_free (pgc->bf); @@ -2886,7 +2891,7 @@ handle_p2p_get (void *cls, #if DEBUG_FS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dropping query from `%s' due to TTL underflow.\n", - GNUNET_h2s (other)); + GNUNET_i2s (other)); #endif /* integer underflow => drop (should be very rare)! */ if (NULL != pgc->bf) -- 2.25.1