aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_search.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-07-12 20:29:25 +0000
committerChristian Grothoff <christian@grothoff.org>2014-07-12 20:29:25 +0000
commitd1248e6a3d5603b4176dd67d7af720ac5d459126 (patch)
tree9e1f5f5fdf379c76d308e7ed91292a9b4d92fc7d /src/fs/fs_search.c
parenta0c135cba1d033ea9cb04a6aa3ec269d82769fc2 (diff)
downloadgnunet-d1248e6a3d5603b4176dd67d7af720ac5d459126.tar.gz
gnunet-d1248e6a3d5603b4176dd67d7af720ac5d459126.zip
fix #3446
Diffstat (limited to 'src/fs/fs_search.c')
-rw-r--r--src/fs/fs_search.c125
1 files changed, 101 insertions, 24 deletions
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 7e4e38b27..d4f0770e3 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -542,14 +542,16 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc,
542 GNUNET_assert (NULL != sc); 542 GNUNET_assert (NULL != sc);
543 GNUNET_FS_uri_to_key (uri, &key); 543 GNUNET_FS_uri_to_key (uri, &key);
544 if (GNUNET_SYSERR == 544 if (GNUNET_SYSERR ==
545 GNUNET_CONTAINER_multihashmap_get_multiple (ent->results, &key, 545 GNUNET_CONTAINER_multihashmap_get_multiple (ent->results,
546 &key,
546 &test_result_present, 547 &test_result_present,
547 (void *) uri)) 548 (void *) uri))
548 return; /* duplicate result */ 549 return; /* duplicate result */
549 /* try to find search result in master map */ 550 /* try to find search result in master map */
550 grc.sr = NULL; 551 grc.sr = NULL;
551 grc.uri = uri; 552 grc.uri = uri;
552 GNUNET_CONTAINER_multihashmap_get_multiple (sc->master_result_map, &key, 553 GNUNET_CONTAINER_multihashmap_get_multiple (sc->master_result_map,
554 &key,
553 &get_result_present, &grc); 555 &get_result_present, &grc);
554 sr = grc.sr; 556 sr = grc.sr;
555 is_new = (NULL == sr) || (sr->mandatory_missing > 0); 557 is_new = (NULL == sr) || (sr->mandatory_missing > 0);
@@ -571,16 +573,34 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc,
571 { 573 {
572 GNUNET_CONTAINER_meta_data_merge (sr->meta, meta); 574 GNUNET_CONTAINER_meta_data_merge (sr->meta, meta);
573 } 575 }
576 GNUNET_break (GNUNET_OK ==
577 GNUNET_CONTAINER_multihashmap_put (ent->results,
578 &sr->key,
579 sr,
580 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
581
574 koff = ent - sc->requests; 582 koff = ent - sc->requests;
575 GNUNET_assert ( (ent >= sc->requests) && (koff < sc->uri->data.ksk.keywordCount)); 583 GNUNET_assert ( (ent >= sc->requests) &&
584 (koff < sc->uri->data.ksk.keywordCount));
576 sr->keyword_bitmap[koff / 8] |= (1 << (koff % 8)); 585 sr->keyword_bitmap[koff / 8] |= (1 << (koff % 8));
577 /* check if mandatory satisfied */ 586 /* check if mandatory satisfied */
578 if (ent->mandatory) 587 if (1 == GNUNET_CONTAINER_multihashmap_size (ent->results))
579 sr->mandatory_missing--; 588 {
580 else 589 if (ent->mandatory)
581 sr->optional_support++; 590 {
591 GNUNET_break (sr->mandatory_missing > 0);
592 sr->mandatory_missing--;
593 }
594 else
595 {
596 sr->optional_support++;
597 }
598 }
582 if (0 != sr->mandatory_missing) 599 if (0 != sr->mandatory_missing)
600 {
601 GNUNET_break (NULL == sr->client_info);
583 return; 602 return;
603 }
584 if (is_new) 604 if (is_new)
585 notify_client_chk_result (sc, sr); 605 notify_client_chk_result (sc, sr);
586 else 606 else
@@ -649,7 +669,10 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc,
649 GNUNET_FS_search_result_sync_ (sr); 669 GNUNET_FS_search_result_sync_ (sr);
650 GNUNET_FS_search_start_probe_ (sr); 670 GNUNET_FS_search_start_probe_ (sr);
651 /* notify client */ 671 /* notify client */
652 notify_client_chk_result (sc, sr); 672 if (0 == sr->mandatory_missing)
673 notify_client_chk_result (sc, sr);
674 else
675 GNUNET_break (NULL == sr->client_info);
653 /* search for updates */ 676 /* search for updates */
654 if (0 == strlen (id_update)) 677 if (0 == strlen (id_update))
655 return; /* no updates */ 678 return; /* no updates */
@@ -746,11 +769,16 @@ process_kblock (struct GNUNET_FS_SearchContext *sc,
746 } 769 }
747 if (NULL == (uri = GNUNET_FS_uri_parse (&pt[1], &emsg))) 770 if (NULL == (uri = GNUNET_FS_uri_parse (&pt[1], &emsg)))
748 { 771 {
749 GNUNET_break_op (0); /* ublock malformed */ 772 if (GNUNET_FS_VERSION > 0x00090400)
750 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 773 {
751 _("Failed to parse URI `%s': %s\n"), 774 /* we broke this in 0x00090300, so don't bitch
752 &pt[1], 775 too loudly just one version up... */
753 emsg); 776 GNUNET_break_op (0); /* ublock malformed */
777 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
778 _("Failed to parse URI `%s': %s\n"),
779 &pt[1],
780 emsg);
781 }
754 GNUNET_free_non_null (emsg); 782 GNUNET_free_non_null (emsg);
755 return; 783 return;
756 } 784 }
@@ -765,7 +793,10 @@ process_kblock (struct GNUNET_FS_SearchContext *sc,
765 GNUNET_FS_uri_destroy (uri); 793 GNUNET_FS_uri_destroy (uri);
766 return; 794 return;
767 } 795 }
768 process_ksk_result (sc, &sc->requests[i], uri, meta); 796 process_ksk_result (sc,
797 &sc->requests[i],
798 uri,
799 meta);
769 800
770 /* clean up */ 801 /* clean up */
771 GNUNET_CONTAINER_meta_data_destroy (meta); 802 GNUNET_CONTAINER_meta_data_destroy (meta);
@@ -1265,6 +1296,36 @@ search_start (struct GNUNET_FS_Handle *h,
1265 1296
1266 1297
1267/** 1298/**
1299 * Update the 'results' map for the individual keywords with the
1300 * results from the 'global' result set.
1301 *
1302 * @param cls closure, the `struct GNUNET_FS_SearchContext *`
1303 * @param key current key code
1304 * @param value value in the hash map, the `struct GNUNET_FS_SearchResult *`
1305 * @return #GNUNET_YES (we should continue to iterate)
1306 */
1307static int
1308update_sre_result_maps (void *cls,
1309 const struct GNUNET_HashCode *key,
1310 void *value)
1311{
1312 struct GNUNET_FS_SearchContext *sc = cls;
1313 struct GNUNET_FS_SearchResult *sr = value;
1314 unsigned int i;
1315
1316 for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1317 if (0 != (sr->keyword_bitmap[i / 8] & (1 << (i % 8))))
1318 GNUNET_break (GNUNET_OK ==
1319 GNUNET_CONTAINER_multihashmap_put (sc->requests[i].results,
1320 &sr->key,
1321 sr,
1322 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1323
1324 return GNUNET_YES;
1325}
1326
1327
1328/**
1268 * Build the request and actually initiate the search using the 1329 * Build the request and actually initiate the search using the
1269 * GNUnet FS service. 1330 * GNUnet FS service.
1270 * 1331 *
@@ -1295,9 +1356,9 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc)
1295 sre = &sc->requests[i]; 1356 sre = &sc->requests[i];
1296 sre->keyword = GNUNET_strdup (keyword); 1357 sre->keyword = GNUNET_strdup (keyword);
1297 GNUNET_CRYPTO_ecdsa_public_key_derive (&anon_pub, 1358 GNUNET_CRYPTO_ecdsa_public_key_derive (&anon_pub,
1298 keyword, 1359 keyword,
1299 "fs-ublock", 1360 "fs-ublock",
1300 &sre->dpub); 1361 &sre->dpub);
1301 GNUNET_CRYPTO_hash (&sre->dpub, 1362 GNUNET_CRYPTO_hash (&sre->dpub,
1302 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), 1363 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
1303 &sre->uquery); 1364 &sre->uquery);
@@ -1306,6 +1367,9 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc)
1306 sc->mandatory_count++; 1367 sc->mandatory_count++;
1307 sre->results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO); 1368 sre->results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
1308 } 1369 }
1370 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
1371 &update_sre_result_maps,
1372 sc);
1309 } 1373 }
1310 sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg); 1374 sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg);
1311 if (NULL == sc->client) 1375 if (NULL == sc->client)
@@ -1401,11 +1465,15 @@ search_result_suspend (void *cls,
1401 sr->update_search = NULL; 1465 sr->update_search = NULL;
1402 } 1466 }
1403 GNUNET_FS_search_stop_probe_ (sr); 1467 GNUNET_FS_search_stop_probe_ (sr);
1404 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND; 1468 if (0 == sr->mandatory_missing)
1405 pi.value.search.specifics.result_suspend.cctx = sr->client_info; 1469 {
1406 pi.value.search.specifics.result_suspend.meta = sr->meta; 1470 /* client is aware of search result, notify about suspension event */
1407 pi.value.search.specifics.result_suspend.uri = sr->uri; 1471 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND;
1408 sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc); 1472 pi.value.search.specifics.result_suspend.cctx = sr->client_info;
1473 pi.value.search.specifics.result_suspend.meta = sr->meta;
1474 pi.value.search.specifics.result_suspend.uri = sr->uri;
1475 sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
1476 }
1409 GNUNET_break (NULL == sr->client_info); 1477 GNUNET_break (NULL == sr->client_info);
1410 GNUNET_free_non_null (sr->serialization); 1478 GNUNET_free_non_null (sr->serialization);
1411 GNUNET_FS_uri_destroy (sr->uri); 1479 GNUNET_FS_uri_destroy (sr->uri);
@@ -1559,10 +1627,12 @@ search_result_stop (void *cls,
1559 sr->download->search = NULL; 1627 sr->download->search = NULL;
1560 sr->download->top = 1628 sr->download->top =
1561 GNUNET_FS_make_top (sr->download->h, 1629 GNUNET_FS_make_top (sr->download->h,
1562 &GNUNET_FS_download_signal_suspend_, sr->download); 1630 &GNUNET_FS_download_signal_suspend_,
1631 sr->download);
1563 if (NULL != sr->download->serialization) 1632 if (NULL != sr->download->serialization)
1564 { 1633 {
1565 GNUNET_FS_remove_sync_file_ (sc->h, GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD, 1634 GNUNET_FS_remove_sync_file_ (sc->h,
1635 GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD,
1566 sr->download->serialization); 1636 sr->download->serialization);
1567 GNUNET_free (sr->download->serialization); 1637 GNUNET_free (sr->download->serialization);
1568 sr->download->serialization = NULL; 1638 sr->download->serialization = NULL;
@@ -1572,6 +1642,13 @@ search_result_stop (void *cls,
1572 GNUNET_FS_download_sync_ (sr->download); 1642 GNUNET_FS_download_sync_ (sr->download);
1573 sr->download = NULL; 1643 sr->download = NULL;
1574 } 1644 }
1645 if (0 != sr->mandatory_missing)
1646 {
1647 /* client is unaware of search result as
1648 it does not match required keywords */
1649 GNUNET_break (NULL == sr->client_info);
1650 return GNUNET_OK;
1651 }
1575 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED; 1652 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED;
1576 pi.value.search.specifics.result_stopped.cctx = sr->client_info; 1653 pi.value.search.specifics.result_stopped.cctx = sr->client_info;
1577 pi.value.search.specifics.result_stopped.meta = sr->meta; 1654 pi.value.search.specifics.result_stopped.meta = sr->meta;