aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-09-05 13:19:01 +0000
committerChristian Grothoff <christian@grothoff.org>2009-09-05 13:19:01 +0000
commit32e19a47f4e6bd369e99e3d292be7b01c009edac (patch)
tree7a43fdac918d23415b515d47ff837c28ede108fd /src
parent3de7118c925ac03b973655af6bfedc606aa097b4 (diff)
downloadgnunet-32e19a47f4e6bd369e99e3d292be7b01c009edac.tar.gz
gnunet-32e19a47f4e6bd369e99e3d292be7b01c009edac.zip
seach
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs.h120
-rw-r--r--src/fs/fs_search.c449
-rw-r--r--src/include/gnunet_container_lib.h7
-rw-r--r--src/include/gnunet_fs_service.h41
-rw-r--r--src/util/container_multihashmap.c2
5 files changed, 541 insertions, 78 deletions
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 6e793bf8d..ed925d9c8 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -382,6 +382,12 @@ struct GNUNET_FS_Handle
382 */ 382 */
383 struct GNUNET_CLIENT_Connection *client; 383 struct GNUNET_CLIENT_Connection *client;
384 384
385 /**
386 * How many downloads probing availability
387 * of search results do we have running
388 * right now?
389 */
390 unsigned int active_probes;
385 391
386}; 392};
387 393
@@ -583,6 +589,72 @@ struct GNUNET_FS_UnindexContext
583 589
584 590
585/** 591/**
592 * Information we store for each search result.
593 */
594struct SearchResult
595{
596
597 /**
598 * URI to which this search result
599 * refers to.
600 */
601 struct GNUNET_FS_Uri *uri;
602
603 /**
604 * Metadata for the search result.
605 */
606 struct GNUNET_CONTAINER_MetaData *meta;
607
608 /**
609 * Client info for this search result.
610 */
611 void *client_info;
612
613 /**
614 * ID of a job that is currently probing
615 * this results' availability (NULL if we
616 * are not currently probing).
617 */
618 struct GNUNET_FS_DownloadContext *probe_ctx;
619
620 /**
621 * ID of the task that will clean up the probe_ctx
622 * should it not complete on time (and that will
623 * need to be cancelled if we clean up the search
624 * result before then).
625 */
626 GNUNET_SCHEDULER_TaskIdentifier probe_cancel_task;
627
628 /**
629 * Number of mandatory keywords for which
630 * we have NOT yet found the search result;
631 * when this value hits zero, the search
632 * result is given to the callback.
633 */
634 uint32_t mandatory_missing;
635
636 /**
637 * Number of optional keywords under which
638 * this result was also found.
639 */
640 uint32_t optional_support;
641
642 /**
643 * Number of availability tests that
644 * have succeeded for this result.
645 */
646 uint32_t availability_success;
647
648 /**
649 * Number of availability trials that we
650 * have performed for this search result.
651 */
652 uint32_t availability_trials;
653
654};
655
656
657/**
586 * Information we keep for each keyword in 658 * Information we keep for each keyword in
587 * a keyword search. 659 * a keyword search.
588 */ 660 */
@@ -597,7 +669,24 @@ struct SearchRequestEntry
597 /** 669 /**
598 * Hash of the public key, also known as the query. 670 * Hash of the public key, also known as the query.
599 */ 671 */
600 GNUNET_HashCode query; 672 GNUNET_HashCode query;
673
674 /**
675 * Map that contains a "struct SearchResult" for each result that
676 * was found under this keyword. Note that the entries will point
677 * to the same locations as those in the master result map (in
678 * "struct GNUNET_FS_SearchContext"), so they should not be freed.
679 * The key for each entry is the XOR of the key and query in the CHK
680 * URI (as a unique identifier for the search result).
681 */
682 struct GNUNET_CONTAINER_MultiHashMap *results;
683
684 /**
685 * Is this keyword a mandatory keyword
686 * (started with '+')?
687 */
688 int mandatory;
689
601}; 690};
602 691
603 692
@@ -617,12 +706,34 @@ struct GNUNET_FS_SearchContext
617 struct GNUNET_FS_Uri *uri; 706 struct GNUNET_FS_Uri *uri;
618 707
619 /** 708 /**
709 * For update-searches, link to the
710 * base-SKS search that triggered the
711 * update search; otherwise NULL.
712 */
713 struct GNUNET_FS_SearchContext *parent;
714
715 /**
620 * Connection to the FS service. 716 * Connection to the FS service.
621 */ 717 */
622 struct GNUNET_CLIENT_Connection *client; 718 struct GNUNET_CLIENT_Connection *client;
623 719
624 /** 720 /**
721 * Pointer we keep for the client.
722 */
723 void *client_info;
724
725 /**
726 * Map that contains a "struct SearchResult" for each result that
727 * was found in the search. The key for each entry is the XOR of
728 * the key and query in the CHK URI (as a unique identifier for the
729 * search result).
730 */
731 struct GNUNET_CONTAINER_MultiHashMap *master_result_map;
732
733 /**
625 * Per-keyword information for a keyword search. 734 * Per-keyword information for a keyword search.
735 * This array will have exactly as many entries
736 * as there were keywords.
626 */ 737 */
627 struct SearchRequestEntry *requests; 738 struct SearchRequestEntry *requests;
628 739
@@ -644,9 +755,12 @@ struct GNUNET_FS_SearchContext
644 /** 755 /**
645 * Anonymity level for the search. 756 * Anonymity level for the search.
646 */ 757 */
647 unsigned int anonymity; 758 uint32_t anonymity;
648
649 759
760 /**
761 * Number of mandatory keywords in this query.
762 */
763 uint32_t mandatory_count;
650}; 764};
651 765
652 766
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index e855a4d30..109a76791 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -24,9 +24,10 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * TODO: 26 * TODO:
27 * - aggregate and process results (FSUI-style) 27 * - handle SKS updates searches nicely (can wait)
28 * - call progress callbacks 28 * - handle availability probes (can wait)
29 * - make operations persistent (can wait) 29 * - make operations persistent (can wait)
30 * - handle namespace advertisements (can wait)
30 * - add support for pushing "already seen" information 31 * - add support for pushing "already seen" information
31 * to FS service for bloomfilter (can wait) 32 * to FS service for bloomfilter (can wait)
32 */ 33 */
@@ -40,6 +41,150 @@
40#define DEBUG_SEARCH GNUNET_YES 41#define DEBUG_SEARCH GNUNET_YES
41 42
42 43
44
45/**
46 * Fill in all of the generic fields for
47 * a search event.
48 *
49 * @param pc structure to fill in
50 * @param sc overall search context
51 */
52static void
53make_search_status (struct GNUNET_FS_ProgressInfo *pi,
54 struct GNUNET_FS_SearchContext *sc)
55{
56 pi->value.search.sc = sc;
57 pi->value.search.cctx
58 = sc->client_info;
59 pi->value.search.pctx
60 = (sc->parent == NULL) ? NULL : sc->parent->client_info;
61 pi->value.search.query
62 = sc->uri;
63 pi->value.search.duration = GNUNET_TIME_absolute_get_duration (sc->start_time);
64 pi->value.search.anonymity = sc->anonymity;
65}
66
67
68/**
69 * Check if the given result is identical
70 * to the given URI.
71 *
72 * @param cls points to the URI we check against
73 * @param key not used
74 * @param value a "struct SearchResult" who's URI we
75 * should compare with
76 * @return GNUNET_SYSERR if the result is present,
77 * GNUNET_OK otherwise
78 */
79static int
80test_result_present (void *cls,
81 const GNUNET_HashCode * key,
82 void *value)
83{
84 const struct GNUNET_FS_Uri *uri = cls;
85 struct SearchResult *sr = value;
86
87 if (GNUNET_FS_uri_test_equal (uri,
88 sr->uri))
89 return GNUNET_SYSERR;
90 return GNUNET_OK;
91}
92
93
94/**
95 * We've found a new CHK result. Let the client
96 * know about it.
97 *
98 * @param sc the search context
99 * @param sr the specific result
100 */
101static void
102notify_client_chk_result (struct GNUNET_FS_SearchContext *sc,
103 struct SearchResult *sr)
104{
105 struct GNUNET_FS_ProgressInfo pi;
106
107 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT;
108 make_search_status (&pi, sc);
109 pi.value.search.specifics.result.meta = sr->meta;
110 pi.value.search.specifics.result.uri = sr->uri;
111 sr->client_info = sc->h->upcb (sc->h->upcb_cls,
112 &pi);
113}
114
115
116/**
117 * We've found new information about an existing CHK result. Let the
118 * client know about it.
119 *
120 * @param sc the search context
121 * @param sr the specific result
122 */
123static void
124notify_client_chk_update (struct GNUNET_FS_SearchContext *sc,
125 struct SearchResult *sr)
126{
127 struct GNUNET_FS_ProgressInfo pi;
128
129 pi.status = GNUNET_FS_STATUS_SEARCH_UPDATE;
130 make_search_status (&pi, sc);
131 pi.value.search.specifics.update.cctx = sr->client_info;
132 pi.value.search.specifics.update.meta = sr->meta;
133 pi.value.search.specifics.update.uri = sr->uri;
134 pi.value.search.specifics.update.availability_rank
135 = 2*sr->availability_success - sr->availability_trials;
136 pi.value.search.specifics.update.availability_certainty
137 = sr->availability_trials;
138 pi.value.search.specifics.update.applicability_rank
139 = sr->optional_support;
140 sr->client_info = sc->h->upcb (sc->h->upcb_cls,
141 &pi);
142}
143
144
145/**
146 * Context for "get_result_present".
147 */
148struct GetResultContext
149{
150 /**
151 * The URI we're looking for.
152 */
153 const struct GNUNET_FS_Uri *uri;
154
155 /**
156 * Where to store a pointer to the search
157 * result struct if we found a match.
158 */
159 struct SearchResult *sr;
160};
161
162
163/**
164 * Check if the given result is identical
165 * to the given URI and if so return it.
166 *
167 * @param cls a "struct GetResultContext"
168 * @param key not used
169 * @param value a "struct SearchResult" who's URI we
170 * should compare with
171 * @return GNUNET_OK
172 */
173static int
174get_result_present (void *cls,
175 const GNUNET_HashCode * key,
176 void *value)
177{
178 struct GetResultContext *grc = cls;
179 struct SearchResult *sr = value;
180
181 if (GNUNET_FS_uri_test_equal (grc->uri,
182 sr->uri))
183 grc->sr = sr;
184 return GNUNET_OK;
185}
186
187
43/** 188/**
44 * We have received a KSK result. Check 189 * We have received a KSK result. Check
45 * how it fits in with the overall query 190 * how it fits in with the overall query
@@ -57,13 +202,83 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc,
57 const struct GNUNET_FS_Uri *uri, 202 const struct GNUNET_FS_Uri *uri,
58 const struct GNUNET_CONTAINER_MetaData *meta) 203 const struct GNUNET_CONTAINER_MetaData *meta)
59{ 204{
60 // FIXME: check if new 205 GNUNET_HashCode key;
61 // FIXME: check if mandatory satisfied 206 struct SearchResult *sr;
62 // FIXME: notify client! 207 struct GetResultContext grc;
208 int is_new;
209
210 /* check if new */
211 if (! GNUNET_FS_uri_test_ksk (uri))
212 {
213 GNUNET_break_op (0);
214 return;
215 }
216 GNUNET_CRYPTO_hash_xor (&uri->data.chk.chk.key,
217 &uri->data.chk.chk.query,
218 &key);
219 if (GNUNET_SYSERR ==
220 GNUNET_CONTAINER_multihashmap_get_multiple (ent->results,
221 &key,
222 &test_result_present,
223 (void*) uri))
224 return; /* duplicate result */
225 /* try to find search result in master map */
226 grc.sr = NULL;
227 grc.uri = uri;
228 GNUNET_CONTAINER_multihashmap_get_multiple (sc->master_result_map,
229 &key,
230 &get_result_present,
231 &grc);
232 sr = grc.sr;
233 is_new = (NULL == sr) || (sr->mandatory_missing > 0);
234 if (NULL == sr)
235 {
236 sr = GNUNET_malloc (sizeof (struct SearchResult));
237 sr->uri = GNUNET_FS_uri_dup (uri);
238 sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
239 sr->mandatory_missing = sc->mandatory_count;
240 GNUNET_CONTAINER_multihashmap_put (sc->master_result_map,
241 &key,
242 sr,
243 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
244 }
245 else
246 {
247 /* FIXME: consider combining the meta data */
248 }
249 /* check if mandatory satisfied */
250 if (ent->mandatory)
251 sr->mandatory_missing--;
252 else
253 sr->optional_support++;
254 if (0 != sr->mandatory_missing)
255 return;
256 if (is_new)
257 notify_client_chk_result (sc, sr);
258 else
259 notify_client_chk_update (sc, sr);
260 /* FIXME: consider starting probes for "sr" */
63} 261}
64 262
65 263
66/** 264/**
265 * Start search for content, internal API.
266 *
267 * @param h handle to the file sharing subsystem
268 * @param uri specifies the search parameters; can be
269 * a KSK URI or an SKS URI.
270 * @param anonymity desired level of anonymity
271 * @param parent parent search (for namespace update searches)
272 * @return context that can be used to control the search
273 */
274static struct GNUNET_FS_SearchContext *
275search_start (struct GNUNET_FS_Handle *h,
276 const struct GNUNET_FS_Uri *uri,
277 unsigned int anonymity,
278 struct GNUNET_FS_SearchContext *parent);
279
280
281/**
67 * We have received an SKS result. Start 282 * We have received an SKS result. Start
68 * searching for updates and notify the 283 * searching for updates and notify the
69 * client if it is a new result. 284 * client if it is a new result.
@@ -79,21 +294,49 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc,
79 const struct GNUNET_FS_Uri *uri, 294 const struct GNUNET_FS_Uri *uri,
80 const struct GNUNET_CONTAINER_MetaData *meta) 295 const struct GNUNET_CONTAINER_MetaData *meta)
81{ 296{
82 // FIXME: check if new 297 struct GNUNET_FS_Uri uu;
83 // FIXME: notify client 298 GNUNET_HashCode key;
299 struct SearchResult *sr;
84 300
85 if (strlen (id_update) > 0) 301 /* check if new */
302 if (! GNUNET_FS_uri_test_ksk (uri))
86 { 303 {
87 // FIXME: search for updates! 304 GNUNET_break_op (0);
88#if 0 305 return;
89 updateURI.type = sks;
90 GNUNET_hash (&sb->subspace,
91 sizeof (GNUNET_RSA_PublicKey),
92 &updateURI.data.sks.namespace);
93 updateURI.data.sks.identifier = GNUNET_strdup (id);
94 add_search_for_uri (&updateURI, sqc);
95#endif
96 } 306 }
307 GNUNET_CRYPTO_hash_xor (&uri->data.chk.chk.key,
308 &uri->data.chk.chk.query,
309 &key);
310 if (GNUNET_SYSERR ==
311 GNUNET_CONTAINER_multihashmap_get_multiple (sc->master_result_map,
312 &key,
313 &test_result_present,
314 (void*) uri))
315 return; /* duplicate result */
316 sr = GNUNET_malloc (sizeof (struct SearchResult));
317 sr->uri = GNUNET_FS_uri_dup (uri);
318 sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
319 GNUNET_CONTAINER_multihashmap_put (sc->master_result_map,
320 &key,
321 sr,
322 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
323 /* FIXME: consider starting probes for "sr" */
324
325 /* notify client */
326 notify_client_chk_result (sc, sr);
327 /* search for updates */
328 if (strlen (id_update) == 0)
329 return; /* no updates */
330 uu.type = sks;
331 uu.data.sks.namespace = sc->uri->data.sks.namespace;
332 uu.data.sks.identifier = GNUNET_strdup (id_update);
333 /* FIXME: should attach update search
334 to the individual result, not
335 the entire SKS search! */
336 search_start (sc->h,
337 &uu,
338 sc->anonymity,
339 sc);
97} 340}
98 341
99 342
@@ -371,12 +614,8 @@ transmit_search_request (void *cls,
371 size_t msize; 614 size_t msize;
372 struct SearchMessage *sm; 615 struct SearchMessage *sm;
373 unsigned int i; 616 unsigned int i;
374 const char *keyword;
375 const char *identifier; 617 const char *identifier;
376 GNUNET_HashCode idh; 618 GNUNET_HashCode idh;
377 GNUNET_HashCode hc;
378 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
379 struct GNUNET_CRYPTO_RsaPrivateKey *pk;
380 619
381 if (NULL == buf) 620 if (NULL == buf)
382 { 621 {
@@ -389,26 +628,12 @@ transmit_search_request (void *cls,
389 GNUNET_assert (size >= msize); 628 GNUNET_assert (size >= msize);
390 sm = buf; 629 sm = buf;
391 memset (sm, 0, msize); 630 memset (sm, 0, msize);
392 sc->requests = GNUNET_malloc (sizeof (struct SearchRequestEntry) *
393 sc->uri->data.ksk.keywordCount);
394 for (i=0;i<sc->uri->data.ksk.keywordCount;i++) 631 for (i=0;i<sc->uri->data.ksk.keywordCount;i++)
395 { 632 {
396 sm[i].header.size = htons (sizeof (struct SearchMessage)); 633 sm[i].header.size = htons (sizeof (struct SearchMessage));
397 sm[i].header.type = htons (GNUNET_MESSAGE_TYPE_FS_START_SEARCH); 634 sm[i].header.type = htons (GNUNET_MESSAGE_TYPE_FS_START_SEARCH);
398 sm[i].anonymity_level = htonl (sc->anonymity); 635 sm[i].anonymity_level = htonl (sc->anonymity);
399 keyword = &sc->uri->data.ksk.keywords[i][1]; 636 sm[i].query = sc->requests[i].query;
400
401 GNUNET_CRYPTO_hash (keyword, strlen (keyword), &hc);
402 pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&hc);
403 GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
404 GNUNET_CRYPTO_rsa_key_free (pk);
405 GNUNET_CRYPTO_hash (&pub,
406 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
407 &sm[i].query);
408 sc->requests[i].query = sm[i].query;
409 GNUNET_CRYPTO_hash (keyword,
410 strlen (keyword),
411 &sc->requests[i].key);
412 } 637 }
413 } 638 }
414 else 639 else
@@ -501,22 +726,30 @@ try_reconnect (struct GNUNET_FS_SearchContext *sc)
501 726
502 727
503/** 728/**
504 * Start search for content. 729 * Start search for content, internal API.
505 * 730 *
506 * @param h handle to the file sharing subsystem 731 * @param h handle to the file sharing subsystem
507 * @param uri specifies the search parameters; can be 732 * @param uri specifies the search parameters; can be
508 * a KSK URI or an SKS URI. 733 * a KSK URI or an SKS URI.
509 * @param anonymity desired level of anonymity 734 * @param anonymity desired level of anonymity
735 * @param parent parent search (for namespace update searches)
510 * @return context that can be used to control the search 736 * @return context that can be used to control the search
511 */ 737 */
512struct GNUNET_FS_SearchContext * 738static struct GNUNET_FS_SearchContext *
513GNUNET_FS_search_start (struct GNUNET_FS_Handle *h, 739search_start (struct GNUNET_FS_Handle *h,
514 const struct GNUNET_FS_Uri *uri, 740 const struct GNUNET_FS_Uri *uri,
515 unsigned int anonymity) 741 unsigned int anonymity,
742 struct GNUNET_FS_SearchContext *parent)
516{ 743{
517 struct GNUNET_FS_SearchContext *sc; 744 struct GNUNET_FS_SearchContext *sc;
518 struct GNUNET_CLIENT_Connection *client; 745 struct GNUNET_CLIENT_Connection *client;
746 struct GNUNET_FS_ProgressInfo pi;
519 size_t size; 747 size_t size;
748 unsigned int i;
749 const char *keyword;
750 GNUNET_HashCode hc;
751 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
752 struct GNUNET_CRYPTO_RsaPrivateKey *pk;
520 753
521 if (GNUNET_FS_uri_test_ksk (uri)) 754 if (GNUNET_FS_uri_test_ksk (uri))
522 { 755 {
@@ -544,7 +777,38 @@ GNUNET_FS_search_start (struct GNUNET_FS_Handle *h,
544 sc->anonymity = anonymity; 777 sc->anonymity = anonymity;
545 sc->start_time = GNUNET_TIME_absolute_get (); 778 sc->start_time = GNUNET_TIME_absolute_get ();
546 sc->client = client; 779 sc->client = client;
547 // FIXME: call callback! 780 sc->parent = parent;
781 sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16);
782
783 sc->requests = GNUNET_malloc (sizeof (struct SearchRequestEntry) *
784 sc->uri->data.ksk.keywordCount);
785 for (i=0;i<sc->uri->data.ksk.keywordCount;i++)
786 {
787 keyword = &sc->uri->data.ksk.keywords[i][1];
788 GNUNET_CRYPTO_hash (keyword, strlen (keyword), &hc);
789 pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&hc);
790 GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
791 GNUNET_CRYPTO_rsa_key_free (pk);
792 GNUNET_CRYPTO_hash (&pub,
793 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
794 &sc->requests[i].query);
795 sc->requests[i].mandatory = (sc->uri->data.ksk.keywords[i][0] == '+');
796 if (sc->requests[i].mandatory)
797 sc->mandatory_count++;
798 sc->requests[i].results = GNUNET_CONTAINER_multihashmap_create (4);
799 GNUNET_CRYPTO_hash (keyword,
800 strlen (keyword),
801 &sc->requests[i].key);
802 }
803 if (NULL != parent)
804 {
805 // FIXME: need to track children
806 // in parent in case parent is stopped!
807 }
808 pi.status = GNUNET_FS_STATUS_SEARCH_START;
809 make_search_status (&pi, sc);
810 sc->client_info = h->upcb (h->upcb_cls,
811 &pi);
548 GNUNET_CLIENT_notify_transmit_ready (client, 812 GNUNET_CLIENT_notify_transmit_ready (client,
549 size, 813 size,
550 GNUNET_CONSTANTS_SERVICE_TIMEOUT, 814 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
@@ -555,6 +819,24 @@ GNUNET_FS_search_start (struct GNUNET_FS_Handle *h,
555 819
556 820
557/** 821/**
822 * Start search for content.
823 *
824 * @param h handle to the file sharing subsystem
825 * @param uri specifies the search parameters; can be
826 * a KSK URI or an SKS URI.
827 * @param anonymity desired level of anonymity
828 * @return context that can be used to control the search
829 */
830struct GNUNET_FS_SearchContext *
831GNUNET_FS_search_start (struct GNUNET_FS_Handle *h,
832 const struct GNUNET_FS_Uri *uri,
833 unsigned int anonymity)
834{
835 return search_start (h, uri, anonymity, NULL);
836}
837
838
839/**
558 * Pause search. 840 * Pause search.
559 * 841 *
560 * @param sc context for the search that should be paused 842 * @param sc context for the search that should be paused
@@ -562,6 +844,8 @@ GNUNET_FS_search_start (struct GNUNET_FS_Handle *h,
562void 844void
563GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc) 845GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc)
564{ 846{
847 struct GNUNET_FS_ProgressInfo pi;
848
565 if (sc->task != GNUNET_SCHEDULER_NO_TASK) 849 if (sc->task != GNUNET_SCHEDULER_NO_TASK)
566 GNUNET_SCHEDULER_cancel (sc->h->sched, 850 GNUNET_SCHEDULER_cancel (sc->h->sched,
567 sc->task); 851 sc->task);
@@ -570,7 +854,11 @@ GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc)
570 GNUNET_CLIENT_disconnect (sc->client); 854 GNUNET_CLIENT_disconnect (sc->client);
571 sc->client = NULL; 855 sc->client = NULL;
572 // FIXME: make persistent! 856 // FIXME: make persistent!
573 // FIXME: call callback! 857 // FIXME: should this freeze all active probes?
858 pi.status = GNUNET_FS_STATUS_SEARCH_PAUSED;
859 make_search_status (&pi, sc);
860 sc->client_info = sc->h->upcb (sc->h->upcb_cls,
861 &pi);
574} 862}
575 863
576 864
@@ -582,11 +870,64 @@ GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc)
582void 870void
583GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc) 871GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc)
584{ 872{
873 struct GNUNET_FS_ProgressInfo pi;
874
585 GNUNET_assert (sc->client == NULL); 875 GNUNET_assert (sc->client == NULL);
586 GNUNET_assert (sc->task == GNUNET_SCHEDULER_NO_TASK); 876 GNUNET_assert (sc->task == GNUNET_SCHEDULER_NO_TASK);
587 do_reconnect (sc, NULL); 877 do_reconnect (sc, NULL);
588 // FIXME: make persistent! 878 // FIXME: make persistent!
589 // FIXME: call callback! 879 pi.status = GNUNET_FS_STATUS_SEARCH_CONTINUED;
880 make_search_status (&pi, sc);
881 sc->client_info = sc->h->upcb (sc->h->upcb_cls,
882 &pi);
883}
884
885
886/**
887 * Free the given search result.
888 *
889 * @param cls the global FS handle
890 * @param key the key for the search result (unused)
891 * @param value the search result to free
892 * @return GNUNET_OK
893 */
894static int
895search_result_free (void *cls,
896 const GNUNET_HashCode * key,
897 void *value)
898{
899 struct GNUNET_FS_SearchContext *sc = cls;
900 struct GNUNET_FS_Handle *h = sc->h;
901 struct SearchResult *sr = value;
902 struct GNUNET_FS_ProgressInfo pi;
903
904 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED;
905 make_search_status (&pi, sc);
906 pi.value.search.specifics.result_stopped.cctx = sr->client_info;
907 pi.value.search.specifics.result_stopped.meta = sr->meta;
908 pi.value.search.specifics.result_stopped.uri = sr->uri;
909 sr->client_info = h->upcb (h->upcb_cls,
910 &pi);
911 GNUNET_break (NULL == sr->client_info);
912
913 GNUNET_FS_uri_destroy (sr->uri);
914 GNUNET_CONTAINER_meta_data_destroy (sr->meta);
915 if (sr->probe_ctx != NULL)
916 {
917 GNUNET_FS_file_download_stop (sr->probe_ctx, GNUNET_YES);
918 h->active_probes--;
919 /* FIXME: trigger starting of new
920 probes here!? Maybe not -- could
921 cause new probes to be immediately
922 stopped again... */
923 }
924 if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
925 {
926 GNUNET_SCHEDULER_cancel (h->sched,
927 sr->probe_cancel_task);
928 }
929 GNUNET_free (sr);
930 return GNUNET_OK;
590} 931}
591 932
592 933
@@ -598,13 +939,31 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc)
598void 939void
599GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc) 940GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc)
600{ 941{
942 struct GNUNET_FS_ProgressInfo pi;
943 unsigned int i;
944
601 // FIXME: make un-persistent! 945 // FIXME: make un-persistent!
602 // FIXME: call callback! 946 if (NULL != sc->parent)
947 {
948 // FIXME: need to untrack sc
949 // in parent!
950 }
951 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
952 &search_result_free,
953 sc);
954 pi.status = GNUNET_FS_STATUS_SEARCH_STOPPED;
955 make_search_status (&pi, sc);
956 sc->client_info = sc->h->upcb (sc->h->upcb_cls,
957 &pi);
958 GNUNET_break (NULL == sc->client_info);
603 if (sc->task != GNUNET_SCHEDULER_NO_TASK) 959 if (sc->task != GNUNET_SCHEDULER_NO_TASK)
604 GNUNET_SCHEDULER_cancel (sc->h->sched, 960 GNUNET_SCHEDULER_cancel (sc->h->sched,
605 sc->task); 961 sc->task);
606 if (NULL != sc->client) 962 if (NULL != sc->client)
607 GNUNET_CLIENT_disconnect (sc->client); 963 GNUNET_CLIENT_disconnect (sc->client);
964 GNUNET_CONTAINER_multihashmap_destroy (sc->master_result_map);
965 for (i=0;i<sc->uri->data.ksk.keywordCount;i++)
966 GNUNET_CONTAINER_multihashmap_destroy (sc->requests[i].results);
608 GNUNET_free_non_null (sc->requests); 967 GNUNET_free_non_null (sc->requests);
609 GNUNET_FS_uri_destroy (sc->uri); 968 GNUNET_FS_uri_destroy (sc->uri);
610 GNUNET_free (sc); 969 GNUNET_free (sc);
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h
index 087324174..279d7df59 100644
--- a/src/include/gnunet_container_lib.h
+++ b/src/include/gnunet_container_lib.h
@@ -455,15 +455,16 @@ enum GNUNET_CONTAINER_MultiHashMapOption
455/** 455/**
456 * Iterator over HashCodes. 456 * Iterator over HashCodes.
457 * 457 *
458 * @param cls closure
458 * @param key current key code 459 * @param key current key code
459 * @param value value in the hash map 460 * @param value value in the hash map
460 * @param cls client-defined argument
461 * @return GNUNET_YES if we should continue to 461 * @return GNUNET_YES if we should continue to
462 * iterate, 462 * iterate,
463 * GNUNET_NO if not. 463 * GNUNET_NO if not.
464 */ 464 */
465typedef int (*GNUNET_CONTAINER_HashMapIterator) (const GNUNET_HashCode * key, 465typedef int (*GNUNET_CONTAINER_HashMapIterator) (void *cls,
466 void *value, void *cls); 466 const GNUNET_HashCode * key,
467 void *value);
467 468
468 469
469/** 470/**
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index e8b8d0ba0..15aa85aa0 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -748,7 +748,7 @@ struct GNUNET_FS_ProgressInfo
748 /** 748 /**
749 * What anonymity level is used for this upload? 749 * What anonymity level is used for this upload?
750 */ 750 */
751 unsigned int anonymity; 751 uint32_t anonymity;
752 752
753 /** 753 /**
754 * Additional values for specific events. 754 * Additional values for specific events.
@@ -891,7 +891,7 @@ struct GNUNET_FS_ProgressInfo
891 /** 891 /**
892 * What anonymity level is used for this download? 892 * What anonymity level is used for this download?
893 */ 893 */
894 unsigned int anonymity; 894 uint32_t anonymity;
895 895
896 /** 896 /**
897 * Additional values for specific events. 897 * Additional values for specific events.
@@ -927,11 +927,6 @@ struct GNUNET_FS_ProgressInfo
927 */ 927 */
928 unsigned int depth; 928 unsigned int depth;
929 929
930 /**
931 * Amount of trust we offered to get the block.
932 */
933 unsigned int trust_offered;
934
935 } progress; 930 } progress;
936 931
937 /** 932 /**
@@ -1027,13 +1022,7 @@ struct GNUNET_FS_ProgressInfo
1027 /** 1022 /**
1028 * What anonymity level is used for this search? 1023 * What anonymity level is used for this search?
1029 */ 1024 */
1030 unsigned int anonymity; 1025 uint32_t anonymity;
1031
1032 /**
1033 * How much trust have we been offering for this search
1034 * so far?
1035 */
1036 unsigned int trust_offered;
1037 1026
1038 /** 1027 /**
1039 * Additional values for specific events. 1028 * Additional values for specific events.
@@ -1049,7 +1038,7 @@ struct GNUNET_FS_ProgressInfo
1049 /** 1038 /**
1050 * Metadata for the search result. 1039 * Metadata for the search result.
1051 */ 1040 */
1052 const struct GNUNET_MetaData *meta; 1041 const struct GNUNET_CONTAINER_MetaData *meta;
1053 1042
1054 /** 1043 /**
1055 * URI for the search result. 1044 * URI for the search result.
@@ -1067,7 +1056,7 @@ struct GNUNET_FS_ProgressInfo
1067 /** 1056 /**
1068 * Metadata for the search result. 1057 * Metadata for the search result.
1069 */ 1058 */
1070 const struct GNUNET_MetaData *meta; 1059 const struct GNUNET_CONTAINER_MetaData *meta;
1071 1060
1072 /** 1061 /**
1073 * URI for the search result. 1062 * URI for the search result.
@@ -1078,20 +1067,20 @@ struct GNUNET_FS_ProgressInfo
1078 * Current availability rank (negative: 1067 * Current availability rank (negative:
1079 * unavailable, positive: available) 1068 * unavailable, positive: available)
1080 */ 1069 */
1081 int availability_rank; 1070 int32_t availability_rank;
1082 1071
1083 /** 1072 /**
1084 * On how many total queries is the given 1073 * On how many total queries is the given
1085 * availability_rank based? 1074 * availability_rank based?
1086 */ 1075 */
1087 unsigned int availabiliy_certainty; 1076 uint32_t availabiliy_certainty;
1088 1077
1089 /** 1078 /**
1090 * Updated applicability rank (the larger, 1079 * Updated applicability rank (the larger,
1091 * the better the result fits the search 1080 * the better the result fits the search
1092 * criteria). 1081 * criteria).
1093 */ 1082 */
1094 unsigned int applicabiliy_rank; 1083 uint32_t applicabiliy_rank;
1095 1084
1096 } resume_result; 1085 } resume_result;
1097 1086
@@ -1110,7 +1099,7 @@ struct GNUNET_FS_ProgressInfo
1110 /** 1099 /**
1111 * Metadata for the search result. 1100 * Metadata for the search result.
1112 */ 1101 */
1113 const struct GNUNET_MetaData *meta; 1102 const struct GNUNET_CONTAINER_MetaData *meta;
1114 1103
1115 /** 1104 /**
1116 * URI for the search result. 1105 * URI for the search result.
@@ -1121,20 +1110,20 @@ struct GNUNET_FS_ProgressInfo
1121 * Current availability rank (negative: 1110 * Current availability rank (negative:
1122 * unavailable, positive: available) 1111 * unavailable, positive: available)
1123 */ 1112 */
1124 int availability_rank; 1113 int32_t availability_rank;
1125 1114
1126 /** 1115 /**
1127 * On how many total queries is the given 1116 * On how many total queries is the given
1128 * availability_rank based? 1117 * availability_rank based?
1129 */ 1118 */
1130 unsigned int availabiliy_certainty; 1119 uint32_t availability_certainty;
1131 1120
1132 /** 1121 /**
1133 * Updated applicability rank (the larger, 1122 * Updated applicability rank (the larger,
1134 * the better the result fits the search 1123 * the better the result fits the search
1135 * criteria). 1124 * criteria).
1136 */ 1125 */
1137 unsigned int applicabiliy_rank; 1126 uint32_t applicability_rank;
1138 1127
1139 } update; 1128 } update;
1140 1129
@@ -1158,7 +1147,7 @@ struct GNUNET_FS_ProgressInfo
1158 /** 1147 /**
1159 * Metadata for the search result. 1148 * Metadata for the search result.
1160 */ 1149 */
1161 const struct GNUNET_MetaData *meta; 1150 const struct GNUNET_CONTAINER_MetaData *meta;
1162 1151
1163 /** 1152 /**
1164 * URI for the search result. 1153 * URI for the search result.
@@ -1187,7 +1176,7 @@ struct GNUNET_FS_ProgressInfo
1187 /** 1176 /**
1188 * Metadata for the search result. 1177 * Metadata for the search result.
1189 */ 1178 */
1190 const struct GNUNET_MetaData *meta; 1179 const struct GNUNET_CONTAINER_MetaData *meta;
1191 1180
1192 /** 1181 /**
1193 * URI for the search result. 1182 * URI for the search result.
@@ -1228,7 +1217,7 @@ struct GNUNET_FS_ProgressInfo
1228 } error; 1217 } error;
1229 1218
1230 /** 1219 /**
1231 * Values for all "GNUNET_FS_STATUS_RESULT_NAMESPACE" events. 1220 * Values for all "GNUNET_FS_STATUS_SEARCH_RESULT_NAMESPACE" events.
1232 */ 1221 */
1233 struct { 1222 struct {
1234 1223
diff --git a/src/util/container_multihashmap.c b/src/util/container_multihashmap.c
index a84955eb3..410564a48 100644
--- a/src/util/container_multihashmap.c
+++ b/src/util/container_multihashmap.c
@@ -123,7 +123,7 @@ GNUNET_CONTAINER_multihashmap_iterate (const struct
123 e = map->map[i]; 123 e = map->map[i];
124 while (e != NULL) 124 while (e != NULL)
125 { 125 {
126 if ((NULL != it) && (GNUNET_OK != it (&e->key, e->value, cls))) 126 if ((NULL != it) && (GNUNET_OK != it (cls, &e->key, e->value)))
127 return GNUNET_SYSERR; 127 return GNUNET_SYSERR;
128 count++; 128 count++;
129 e = e->next; 129 e = e->next;