GNUnet  0.10.x
fs_search.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2014 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
25 #include "platform.h"
26 #include "gnunet_constants.h"
27 #include "gnunet_fs_service.h"
28 #include "gnunet_protocols.h"
29 #include "fs_api.h"
30 #include "fs_publish_ublock.h"
31 
32 
36 #define AVAILABILITY_TRIALS_MAX 8
37 
47 void *
49  struct GNUNET_FS_Handle *h,
51 {
52  void *ret;
53 
54  pi->value.search.sc = sc;
55  pi->value.search.cctx = (NULL != sc) ? sc->client_info : NULL;
56  pi->value.search.pctx =
57  ((NULL == sc) || (NULL == sc->psearch_result))
58  ? NULL
60  pi->value.search.query = (NULL != sc) ? sc->uri : NULL;
61  pi->value.search.duration = (NULL != sc)
64  pi->value.search.anonymity = (NULL != sc) ? sc->anonymity : 0;
65  pi->fsh = h;
66  ret = h->upcb (h->upcb_cls, pi);
67  return ret;
68 }
69 
70 
81 static int
83  const struct GNUNET_HashCode * key,
84  void *value)
85 {
86  const struct GNUNET_FS_Uri *uri = cls;
87  struct GNUNET_FS_SearchResult *sr = value;
88 
89  if (GNUNET_FS_uri_test_equal (uri, sr->uri))
90  return GNUNET_SYSERR;
91  return GNUNET_OK;
92 }
93 
94 
102 static void
104  struct GNUNET_FS_SearchResult *sr)
105 {
106  struct GNUNET_FS_ProgressInfo pi;
107 
109  pi.value.search.specifics.result.meta = sr->meta;
110  pi.value.search.specifics.result.uri = sr->uri;
111  pi.value.search.specifics.result.result = sr;
112  pi.value.search.specifics.result.applicability_rank = sr->optional_support;
113  sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
114 }
115 
116 
124 static void
126  struct GNUNET_FS_SearchResult *sr)
127 {
128  struct GNUNET_FS_ProgressInfo pi;
129 
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 =
136  pi.value.search.specifics.update.availability_certainty =
138  pi.value.search.specifics.update.applicability_rank = sr->optional_support;
139  pi.value.search.specifics.update.current_probe_time
141  sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
142 }
143 
144 
149 {
153  const struct GNUNET_FS_Uri *uri;
154 
160 };
161 
162 
173 static int
175  const struct GNUNET_HashCode *key,
176  void *value)
177 {
178  struct GetResultContext *grc = cls;
179  struct GNUNET_FS_SearchResult *sr = value;
180 
181  if (GNUNET_FS_uri_test_equal (grc->uri, sr->uri))
182  grc->sr = sr;
183  return GNUNET_OK;
184 }
185 
186 
193 static void
195 {
196  struct GNUNET_FS_ProgressInfo pi;
197 
199  pi.value.search.specifics.update.cctx = sr->client_info;
200  pi.value.search.specifics.update.meta = sr->meta;
201  pi.value.search.specifics.update.uri = sr->uri;
202  pi.value.search.specifics.update.availability_rank
204  pi.value.search.specifics.update.availability_certainty
205  = sr->availability_trials;
206  pi.value.search.specifics.update.applicability_rank = sr->optional_support;
207  pi.value.search.specifics.update.current_probe_time
209  sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->h, sr->sc);
211 }
212 
213 
219 static void
221 {
222  struct GNUNET_FS_SearchResult *sr = cls;
223 
224  sr->probe_cancel_task = NULL;
225  sr->availability_trials++;
227  sr->probe_ctx = NULL;
231  "Probe #%u for search result %p failed\n",
233  sr);
234  signal_probe_result (sr);
235 }
236 
237 
243 static void
245 {
246  struct GNUNET_FS_SearchResult *sr = cls;
247 
248  sr->probe_cancel_task = NULL;
249  sr->availability_trials++;
250  sr->availability_success++;
252  sr->probe_ctx = NULL;
256  "Probe #%u for search result %p succeeded\n",
258  sr);
259  signal_probe_result (sr);
260 }
261 
262 
278 void *
280  const struct GNUNET_FS_ProgressInfo *info)
281 {
282  struct GNUNET_FS_SearchResult *sr = info->value.download.cctx;
283  struct GNUNET_TIME_Relative dur;
284 
285  switch (info->status)
286  {
288  /* ignore */
289  break;
291  /* probes should never be resumed */
292  GNUNET_assert (0);
293  break;
295  /* probes should never be suspended */
296  GNUNET_break (0);
297  break;
299  /* ignore */
300  break;
302  if (NULL != sr->probe_cancel_task)
303  {
305  sr->probe_cancel_task = NULL;
306  }
307  sr->probe_cancel_task =
309  &probe_failure_handler, sr);
310  break;
312  if (NULL != sr->probe_cancel_task)
313  {
315  sr->probe_cancel_task = NULL;
316  }
317  sr->probe_cancel_task =
319  break;
321  if (NULL != sr->probe_cancel_task)
322  {
324  sr->probe_cancel_task = NULL;
325  }
326  sr = NULL;
327  break;
329  if (NULL == sr->probe_cancel_task)
330  {
332  sr->probe_cancel_task =
334  &probe_failure_handler, sr);
335  }
336  break;
338  if (NULL != sr->probe_cancel_task)
339  {
341  sr->probe_cancel_task = NULL;
342  }
346  if (0 == sr->remaining_probe_time.rel_value_us)
347  sr->probe_cancel_task =
350  break;
351  default:
352  GNUNET_break (0);
353  return NULL;
354  }
355  return sr;
356 }
357 
358 
364 static void
366 {
367  struct GNUNET_FS_Handle *h = cls;
368  struct GNUNET_FS_SearchResult *sr;
369 
370  for (sr = h->probes_head; NULL != sr; sr = sr->next)
371  if (NULL != sr->probe_ctx->mq)
372  signal_probe_result (sr);
373  h->probe_ping_task
376  h);
377 }
378 
379 
385 static void
387 {
388  struct GNUNET_FS_Handle *h = sr->h;
389 
391  h->probes_tail,
392  sr);
393  if (NULL == h->probe_ping_task)
394  h->probe_ping_task
396  h);
397 }
398 
399 
405 void
407 {
408  struct GNUNET_FS_Handle *h = sr->h;
409 
411  h->probes_tail,
412  sr);
413  if (NULL == h->probes_head)
414  {
416  h->probe_ping_task = NULL;
417  }
418 }
419 
420 
426 void
428 {
429  uint64_t off;
430  uint64_t len;
431 
432  if (NULL != sr->probe_ctx)
433  return;
434  if (NULL != sr->download)
435  return;
436  if (0 == (sr->h->flags & GNUNET_FS_FLAGS_DO_PROBES))
437  return;
439  return;
440  if ( (GNUNET_FS_URI_CHK != sr->uri->type) && (GNUNET_FS_URI_LOC != sr->uri->type))
441  return;
443  if (0 == len)
444  return;
445  if ((len <= DBLOCK_SIZE) && (sr->availability_success > 0))
446  return;
447  off = len / DBLOCK_SIZE;
448  if (off > 0)
450  off *= DBLOCK_SIZE;
451  if (len - off < DBLOCK_SIZE)
452  len = len - off;
453  else
454  len = DBLOCK_SIZE;
456  "Starting probe #%u (at offset %llu) for search result %p\n",
457  sr->availability_trials + 1,
458  (unsigned long long) off,
459  sr);
462  2 * (1 + sr->availability_trials));
463  sr->probe_ctx =
464  GNUNET_FS_download_start (sr->h, sr->uri, sr->meta, NULL, NULL, off,
465  len, sr->anonymity,
467  GNUNET_FS_DOWNLOAD_IS_PROBE, sr, NULL);
469 }
470 
471 
482 struct GNUNET_FS_SearchResult *
484  const struct GNUNET_FS_Uri *uri,
485  const struct GNUNET_CONTAINER_MetaData *meta,
486  void *client_info,
487  uint32_t anonymity)
488 {
489  struct GNUNET_FS_SearchResult *sr;
490 
491  GNUNET_assert (NULL != h);
492  sr = GNUNET_new (struct GNUNET_FS_SearchResult);
493  sr->h = h;
494  sr->uri = GNUNET_FS_uri_dup (uri);
496  sr->client_info = client_info;
497  sr->anonymity = anonymity;
499  return sr;
500 }
501 
502 
508 static void
510 {
511  if (NULL != sr->probe_ctx)
512  {
514  sr->probe_ctx = NULL;
516  }
517  if (NULL != sr->probe_cancel_task)
518  {
520  sr->probe_cancel_task = NULL;
521  }
522 }
523 
524 
532 void *
534 {
535  void *client_info;
536 
537  GNUNET_assert (NULL == sr->sc);
541  client_info = sr->client_info;
542  GNUNET_free (sr);
543  return client_info;
544 }
545 
546 
557 static void
559  struct SearchRequestEntry *ent,
560  const struct GNUNET_FS_Uri *uri,
561  const struct GNUNET_CONTAINER_MetaData *meta)
562 {
563  struct GNUNET_HashCode key;
564  struct GNUNET_FS_SearchResult *sr;
565  struct GetResultContext grc;
566  int is_new;
567  unsigned int koff;
568 
569  /* check if new */
570  GNUNET_assert (NULL != sc);
571  if (GNUNET_OK !=
573  &key))
574  {
575  GNUNET_break_op (0);
576  return;
577  }
578  if (GNUNET_SYSERR ==
580  &key,
582  (void *) uri))
583  return; /* duplicate result */
584  /* try to find search result in master map */
585  grc.sr = NULL;
586  grc.uri = uri;
588  &key,
589  &get_result_present, &grc);
590  sr = grc.sr;
591  is_new = (NULL == sr) || (sr->mandatory_missing > 0);
592  if (NULL == sr)
593  {
594  sr = GNUNET_new (struct GNUNET_FS_SearchResult);
595  sr->h = sc->h;
596  sr->sc = sc;
597  sr->anonymity = sc->anonymity;
598  sr->uri = GNUNET_FS_uri_dup (uri);
601  sr->key = key;
602  sr->keyword_bitmap = GNUNET_malloc ((sc->uri->data.ksk.keywordCount + 7) / 8); /* round up, count bits */
605  }
606  else
607  {
609  }
612  &sr->key,
613  sr,
615 
616  koff = ent - sc->requests;
617  GNUNET_assert ( (ent >= sc->requests) &&
618  (koff < sc->uri->data.ksk.keywordCount));
619  sr->keyword_bitmap[koff / 8] |= (1 << (koff % 8));
620  /* check if mandatory satisfied */
622  {
623  if (ent->mandatory)
624  {
626  sr->mandatory_missing--;
627  }
628  else
629  {
630  sr->optional_support++;
631  }
632  }
633  if (0 != sr->mandatory_missing)
634  {
635  GNUNET_break (NULL == sr->client_info);
636  return;
637  }
638  if (is_new)
639  notify_client_chk_result (sc, sr);
640  else
641  notify_client_chk_update (sc, sr);
644 }
645 
646 
659 static struct GNUNET_FS_SearchContext *
661  const struct GNUNET_FS_Uri *uri,
662  uint32_t anonymity,
664  void *cctx,
665  struct GNUNET_FS_SearchResult *psearch);
666 
667 
677 static void
679  const char *id_update,
680  const struct GNUNET_FS_Uri *uri,
681  const struct GNUNET_CONTAINER_MetaData *meta)
682 {
683  struct GNUNET_FS_Uri uu;
684  struct GNUNET_HashCode key;
685  struct GNUNET_FS_SearchResult *sr;
686 
687  /* check if new */
688  GNUNET_assert (NULL != sc);
689  if (GNUNET_OK !=
691  &key))
692  {
693  GNUNET_break (0);
694  return;
695  }
697  &uri->data.chk.chk.query,
698  &key);
699  if (GNUNET_SYSERR ==
702  (void *) uri))
703  return; /* duplicate result */
704  sr = GNUNET_new (struct GNUNET_FS_SearchResult);
705  sr->h = sc->h;
706  sr->sc = sc;
707  sr->anonymity = sc->anonymity;
708  sr->uri = GNUNET_FS_uri_dup (uri);
710  sr->key = key;
715  /* notify client */
716  if (0 == sr->mandatory_missing)
717  notify_client_chk_result (sc, sr);
718  else
719  GNUNET_break (NULL == sr->client_info);
720  /* search for updates */
721  if (0 == strlen (id_update))
722  return; /* no updates */
723  uu.type = GNUNET_FS_URI_SKS;
724  uu.data.sks.ns = sc->uri->data.sks.ns;
725  uu.data.sks.identifier = GNUNET_strdup (id_update);
726  (void) search_start (sc->h, &uu, sc->anonymity, sc->options, NULL, sr);
727  GNUNET_free (uu.data.sks.identifier);
728 }
729 
730 
745 static int
747  const struct GNUNET_CRYPTO_EcdsaPublicKey *dpub,
748  const void *edata,
749  size_t edata_size,
750  char *data)
751 {
752  const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon;
753  struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
754  unsigned int i;
755 
756  /* find key */
757  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
758  if (0 == memcmp (dpub,
759  &sc->requests[i].dpub,
760  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
761  break;
762  if (i == sc->uri->data.ksk.keywordCount)
763  {
764  /* oops, does not match any of our keywords!? */
765  GNUNET_break (0);
766  return GNUNET_SYSERR;
767  }
768  /* decrypt */
770  GNUNET_CRYPTO_ecdsa_key_get_public (anon, &anon_pub);
771  GNUNET_FS_ublock_decrypt_ (edata, edata_size,
772  &anon_pub,
773  sc->requests[i].keyword,
774  data);
775  return i;
776 }
777 
778 
788 static void
790  const struct UBlock *ub,
791  size_t size)
792 {
793  size_t j;
794  char pt[size - sizeof (struct UBlock)];
795  const char *eos;
797  struct GNUNET_FS_Uri *uri;
798  char *emsg;
799  int i;
800 
801  if (-1 == (i = decrypt_block_with_keyword (sc,
802  &ub->verification_key,
803  &ub[1],
804  size - sizeof (struct UBlock),
805  pt)))
806  return;
807  /* parse; pt[0] is just '\0', so we skip over that */
808  eos = memchr (&pt[1], '\0', sizeof (pt) - 1);
809  if (NULL == eos)
810  {
811  GNUNET_break_op (0);
812  return;
813  }
814  if (NULL == (uri = GNUNET_FS_uri_parse (&pt[1], &emsg)))
815  {
816  if (GNUNET_FS_VERSION > 0x00090400)
817  {
818  /* we broke this in 0x00090300, so don't bitch
819  too loudly just one version up... */
820  GNUNET_break_op (0); /* ublock malformed */
822  _("Failed to parse URI `%s': %s\n"),
823  &pt[1],
824  emsg);
825  }
826  GNUNET_free_non_null (emsg);
827  return;
828  }
829  j = eos - pt + 1;
830  if (sizeof (pt) == j)
832  else
833  meta = GNUNET_CONTAINER_meta_data_deserialize (&pt[j], sizeof (pt) - j);
834  if (NULL == meta)
835  {
836  GNUNET_break_op (0); /* ublock malformed */
837  GNUNET_FS_uri_destroy (uri);
838  return;
839  }
840  process_ksk_result (sc,
841  &sc->requests[i],
842  uri,
843  meta);
844 
845  /* clean up */
847  GNUNET_FS_uri_destroy (uri);
848 }
849 
850 
860 static void
862  const struct UBlock *ub,
863  size_t size)
864 {
865  size_t len = size - sizeof (struct UBlock);
866  char pt[len];
867  struct GNUNET_FS_Uri *uri;
869  const char *id;
870  const char *uris;
871  size_t off;
872  char *emsg;
873 
874  GNUNET_FS_ublock_decrypt_ (&ub[1], len,
875  &sc->uri->data.sks.ns,
876  sc->uri->data.sks.identifier,
877  pt);
878  /* parse */
879  if (0 == (off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris)))
880  {
881  GNUNET_break_op (0); /* ublock malformed */
882  return;
883  }
884  if (NULL == (meta = GNUNET_CONTAINER_meta_data_deserialize (&pt[off], len - off)))
885  {
886  GNUNET_break_op (0); /* ublock malformed */
887  return;
888  }
889  if (NULL == (uri = GNUNET_FS_uri_parse (uris, &emsg)))
890  {
892  _("Failed to parse URI `%s': %s\n"),
893  uris, emsg);
894  GNUNET_break_op (0); /* ublock malformed */
895  GNUNET_free_non_null (emsg);
897  return;
898  }
899  /* process */
900  process_sks_result (sc, id, uri, meta);
901  /* clean up */
902  GNUNET_FS_uri_destroy (uri);
904 }
905 
906 
914 static void
916 
917 
924 static int
925 check_result (void *cls,
926  const struct ClientPutMessage *cm)
927 {
928  /* payload of any variable size is OK */
929  return GNUNET_OK;
930 }
931 
932 
939 static void
940 handle_result (void *cls,
941  const struct ClientPutMessage *cm)
942 {
943  struct GNUNET_FS_SearchContext *sc = cls;
944  uint16_t msize = ntohs (cm->header.size) - sizeof (*cm);
945  enum GNUNET_BLOCK_Type type = ntohl (cm->type);
946 
948  {
950  "Result received has already expired.\n");
951  return; /* result expired */
952  }
953  switch (type)
954  {
956  if (GNUNET_FS_URI_SKS == sc->uri->type)
957  process_sblock (sc,
958  (const struct UBlock *) &cm[1],
959  msize);
960  else
961  process_kblock (sc,
962  (const struct UBlock *) &cm[1],
963  msize);
964  break;
966  GNUNET_break (0);
967  break;
969  GNUNET_break (0);
970  break;
972  GNUNET_break (0);
973  break;
975  GNUNET_break (0);
976  break;
977  default:
979  _("Got result with unknown block type `%d', ignoring"),
980  type);
981  break;
982  }
983 }
984 
985 
992 static void
994 
995 
1000 {
1004  unsigned int put_cnt;
1005 
1009  unsigned int skip_cnt;
1010 
1015 
1020 
1024  unsigned int keyword_offset;
1025 };
1026 
1027 
1037 static int
1038 build_result_set (void *cls,
1039  const struct GNUNET_HashCode *key,
1040  void *value)
1041 {
1042  struct MessageBuilderContext *mbc = cls;
1043  struct GNUNET_FS_SearchResult *sr = value;
1044 
1045  if ( (NULL != sr->keyword_bitmap) &&
1046  (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))) )
1047  return GNUNET_OK; /* have no match for this keyword yet */
1048  if (mbc->skip_cnt > 0)
1049  {
1050  mbc->skip_cnt--;
1051  return GNUNET_OK;
1052  }
1053  if (0 == mbc->put_cnt)
1054  return GNUNET_SYSERR;
1055  mbc->xoff[--mbc->put_cnt] = *key;
1056 
1057  return GNUNET_OK;
1058 }
1059 
1060 
1070 static int
1071 find_result_set (void *cls,
1072  const struct GNUNET_HashCode *key,
1073  void *value)
1074 {
1075  struct MessageBuilderContext *mbc = cls;
1076  struct GNUNET_FS_SearchResult *sr = value;
1077 
1078  if ( (NULL != sr->keyword_bitmap) &&
1079  (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))) )
1080  return GNUNET_OK; /* have no match for this keyword yet */
1081  mbc->put_cnt++;
1082  return GNUNET_OK;
1083 }
1084 
1085 
1092 static void
1094 {
1095  struct MessageBuilderContext mbc;
1096  struct GNUNET_MQ_Envelope *env;
1097  struct SearchMessage *sm;
1098  struct GNUNET_CRYPTO_EcdsaPublicKey dpub;
1099  unsigned int total_seen_results; /* total number of result hashes to send */
1100  uint32_t options;
1101  unsigned int left;
1102  unsigned int todo;
1103  unsigned int fit;
1104  unsigned int search_request_map_offset;
1105  unsigned int keyword_offset;
1106  int first_call;
1107 
1108  memset (&mbc, 0, sizeof (mbc));
1109  mbc.sc = sc;
1110  if (GNUNET_FS_uri_test_ksk (sc->uri))
1111  {
1112  /* This will calculate the result set size ONLY for
1113  "keyword_offset == 0", so we will have to recalculate
1114  it for the other keywords later! */
1116  &find_result_set,
1117  &mbc);
1118  total_seen_results = mbc.put_cnt;
1119  }
1120  else
1121  {
1122  total_seen_results
1124  }
1125  search_request_map_offset = 0;
1126  keyword_offset = 0;
1127  first_call = GNUNET_YES;
1128  while ( (0 != (left =
1129  (total_seen_results - search_request_map_offset))) ||
1130  (GNUNET_YES == first_call) )
1131  {
1132  first_call = GNUNET_NO;
1133  options = SEARCH_MESSAGE_OPTION_NONE;
1136 
1137  fit = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (*sm)) / sizeof (struct GNUNET_HashCode);
1138  todo = GNUNET_MIN (fit,
1139  left);
1140  env = GNUNET_MQ_msg_extra (sm,
1141  sizeof (struct GNUNET_HashCode) * todo,
1143  mbc.skip_cnt = search_request_map_offset;
1144  mbc.xoff = (struct GNUNET_HashCode *) &sm[1];
1145  sm->type = htonl (GNUNET_BLOCK_TYPE_FS_UBLOCK);
1146  sm->anonymity_level = htonl (sc->anonymity);
1147  memset (&sm->target,
1148  0,
1149  sizeof (struct GNUNET_PeerIdentity));
1150 
1151  if (GNUNET_FS_uri_test_ksk (sc->uri))
1152  {
1153  mbc.keyword_offset = keyword_offset;
1154  /* calculate how many results we can send in this message */
1155  mbc.put_cnt = todo;
1156  /* now build message */
1157  sm->query = sc->requests[keyword_offset].uquery;
1160  &mbc);
1161  search_request_map_offset += todo;
1162  GNUNET_assert (0 == mbc.put_cnt);
1163  GNUNET_assert (total_seen_results >= search_request_map_offset);
1164  if (total_seen_results != search_request_map_offset)
1165  {
1166  /* more requesting to be done... */
1167  sm->options = htonl (options | SEARCH_MESSAGE_OPTION_CONTINUED);
1168  }
1169  else
1170  {
1171  sm->options = htonl (options);
1172  keyword_offset++;
1173  if (sc->uri->data.ksk.keywordCount != keyword_offset)
1174  {
1175  /* more keywords => more requesting to be done... */
1176  first_call = GNUNET_YES;
1177  search_request_map_offset = 0;
1178  mbc.put_cnt = 0;
1179  mbc.keyword_offset = keyword_offset;
1181  &find_result_set,
1182  &mbc);
1183  total_seen_results = mbc.put_cnt;
1184  }
1185  }
1186  }
1187  else
1188  {
1190 
1192  sc->uri->data.sks.identifier,
1193  "fs-ublock",
1194  &dpub);
1195  GNUNET_CRYPTO_hash (&dpub,
1196  sizeof (dpub),
1197  &sm->query);
1198  mbc.put_cnt = todo;
1199  mbc.keyword_offset = 0;
1202  &mbc);
1203  GNUNET_assert (total_seen_results >= search_request_map_offset);
1204  if (total_seen_results != search_request_map_offset)
1205  {
1206  /* more requesting to be done... */
1207  sm->options = htonl (options | SEARCH_MESSAGE_OPTION_CONTINUED);
1208  }
1209  else
1210  {
1211  sm->options = htonl (options);
1212  }
1213  }
1214  GNUNET_MQ_send (sc->mq,
1215  env);
1216  }
1217 }
1218 
1219 
1228 static void
1230  enum GNUNET_MQ_Error error)
1231 {
1232  struct GNUNET_FS_SearchContext *sc = cls;
1233 
1234  if (NULL != sc->mq)
1235  {
1236  GNUNET_MQ_destroy (sc->mq);
1237  sc->mq = NULL;
1238  }
1239  try_reconnect (sc);
1240 }
1241 
1242 
1249 static void
1250 do_reconnect (void *cls)
1251 {
1252  struct GNUNET_FS_SearchContext *sc = cls;
1253  struct GNUNET_MQ_MessageHandler handlers[] = {
1256  struct ClientPutMessage,
1257  sc),
1259  };
1260 
1261  sc->task = NULL;
1262  sc->mq = GNUNET_CLIENT_connect (sc->h->cfg,
1263  "fs",
1264  handlers,
1266  sc);
1267  if (NULL == sc->mq)
1268  {
1269  try_reconnect (sc);
1270  return;
1271  }
1273 }
1274 
1275 
1283 static void
1285 {
1286  if (NULL != sc->mq)
1287  {
1288  GNUNET_MQ_destroy (sc->mq);
1289  sc->mq = NULL;
1290  }
1292  sc->task =
1294  &do_reconnect,
1295  sc);
1296 }
1297 
1298 
1311 static struct GNUNET_FS_SearchContext *
1313  const struct GNUNET_FS_Uri *uri,
1314  uint32_t anonymity,
1316  void *cctx,
1317  struct GNUNET_FS_SearchResult *psearch)
1318 {
1319  struct GNUNET_FS_SearchContext *sc;
1320  struct GNUNET_FS_ProgressInfo pi;
1321 
1322  sc = GNUNET_new (struct GNUNET_FS_SearchContext);
1323  sc->h = h;
1324  sc->options = options;
1325  sc->uri = GNUNET_FS_uri_dup (uri);
1326  sc->anonymity = anonymity;
1327  sc->start_time = GNUNET_TIME_absolute_get ();
1328  if (NULL != psearch)
1329  {
1330  sc->psearch_result = psearch;
1331  psearch->update_search = sc;
1332  }
1334  sc->client_info = cctx;
1336  {
1337  GNUNET_FS_uri_destroy (sc->uri);
1338  GNUNET_CONTAINER_multihashmap_destroy (sc->master_result_map);
1339  GNUNET_free (sc);
1340  return NULL;
1341  }
1344  sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
1345  return sc;
1346 }
1347 
1348 
1358 static int
1360  const struct GNUNET_HashCode *key,
1361  void *value)
1362 {
1363  struct GNUNET_FS_SearchContext *sc = cls;
1364  struct GNUNET_FS_SearchResult *sr = value;
1365  unsigned int i;
1366 
1367  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1368  if (0 != (sr->keyword_bitmap[i / 8] & (1 << (i % 8))))
1371  &sr->key,
1372  sr,
1374 
1375  return GNUNET_YES;
1376 }
1377 
1378 
1386 int
1388 {
1389  unsigned int i;
1390  const char *keyword;
1391  const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon;
1392  struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
1393  struct SearchRequestEntry *sre;
1394 
1395  GNUNET_assert (NULL == sc->mq);
1396  if (GNUNET_FS_uri_test_ksk (sc->uri))
1397  {
1398  GNUNET_assert (0 != sc->uri->data.ksk.keywordCount);
1400  GNUNET_CRYPTO_ecdsa_key_get_public (anon, &anon_pub);
1401  sc->requests
1402  = GNUNET_new_array (sc->uri->data.ksk.keywordCount,
1403  struct SearchRequestEntry);
1404 
1405  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1406  {
1407  keyword = &sc->uri->data.ksk.keywords[i][1];
1408  sre = &sc->requests[i];
1409  sre->keyword = GNUNET_strdup (keyword);
1411  keyword,
1412  "fs-ublock",
1413  &sre->dpub);
1414  GNUNET_CRYPTO_hash (&sre->dpub,
1415  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
1416  &sre->uquery);
1417  sre->mandatory = (sc->uri->data.ksk.keywords[i][0] == '+');
1418  if (sre->mandatory)
1419  sc->mandatory_count++;
1421  }
1424  sc);
1425  }
1426  GNUNET_assert (NULL == sc->task);
1427  do_reconnect (sc);
1428  if (NULL == sc->mq)
1429  {
1431  sc->task = NULL;
1432  return GNUNET_SYSERR;
1433  }
1434  return GNUNET_OK;
1435 }
1436 
1437 
1446 static int
1448  const struct GNUNET_HashCode *key,
1449  void *value)
1450 {
1451  struct GNUNET_FS_SearchResult *sr = value;
1452 
1453  if (NULL != sr->probe_ctx)
1454  {
1456  sr->probe_ctx = NULL;
1458  }
1459  if (NULL != sr->probe_cancel_task)
1460  {
1462  sr->probe_cancel_task = NULL;
1463  }
1464  if (NULL != sr->update_search)
1466  return GNUNET_OK;
1467 }
1468 
1469 
1478 static int
1480  const struct GNUNET_HashCode * key,
1481  void *value)
1482 {
1483  struct GNUNET_FS_SearchResult *sr = value;
1484 
1486  if (NULL != sr->update_search)
1488  return GNUNET_OK;
1489 }
1490 
1491 
1500 static int
1502  const struct GNUNET_HashCode *key,
1503  void *value)
1504 {
1505  struct GNUNET_FS_SearchContext *sc = cls;
1506  struct GNUNET_FS_SearchResult *sr = value;
1507  struct GNUNET_FS_ProgressInfo pi;
1508 
1509  if (NULL != sr->download)
1510  {
1512  sr->download = NULL;
1513  }
1514  if (NULL != sr->update_search)
1515  {
1517  sr->update_search = NULL;
1518  }
1520  if (0 == sr->mandatory_missing)
1521  {
1522  /* client is aware of search result, notify about suspension event */
1524  pi.value.search.specifics.result_suspend.cctx = sr->client_info;
1525  pi.value.search.specifics.result_suspend.meta = sr->meta;
1526  pi.value.search.specifics.result_suspend.uri = sr->uri;
1527  sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
1528  }
1529  GNUNET_break (NULL == sr->client_info);
1531  GNUNET_FS_uri_destroy (sr->uri);
1534  GNUNET_free (sr);
1535  return GNUNET_OK;
1536 }
1537 
1538 
1545 void
1547 {
1548  struct GNUNET_FS_SearchContext *sc = cls;
1549  struct GNUNET_FS_ProgressInfo pi;
1550  unsigned int i;
1551 
1552  GNUNET_FS_end_top (sc->h, sc->top);
1554  &search_result_suspend, sc);
1556  sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
1557  GNUNET_break (NULL == sc->client_info);
1558  if (sc->task != NULL)
1559  {
1561  sc->task = NULL;
1562  }
1563  if (NULL != sc->mq)
1564  {
1565  GNUNET_MQ_destroy (sc->mq);
1566  sc->mq = NULL;
1567  }
1569  if (NULL != sc->requests)
1570  {
1572  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1573  {
1575  GNUNET_free (sc->requests[i].keyword);
1576  }
1577  }
1579  GNUNET_free_non_null (sc->emsg);
1580  GNUNET_FS_uri_destroy (sc->uri);
1582  GNUNET_free (sc);
1583 }
1584 
1585 
1597 struct GNUNET_FS_SearchContext *
1599  const struct GNUNET_FS_Uri *uri, uint32_t anonymity,
1600  enum GNUNET_FS_SearchOptions options, void *cctx)
1601 {
1602  struct GNUNET_FS_SearchContext *ret;
1603 
1604  ret = search_start (h, uri, anonymity, options, cctx, NULL);
1605  if (NULL == ret)
1606  return NULL;
1608  return ret;
1609 }
1610 
1611 
1617 void
1619 {
1620  struct GNUNET_FS_ProgressInfo pi;
1621 
1622  if (NULL != sc->task)
1623  {
1625  sc->task = NULL;
1626  }
1627  if (NULL != sc->mq)
1628  {
1629  GNUNET_MQ_destroy (sc->mq);
1630  sc->mq = NULL;
1631  }
1635  sc);
1638  sc->h,
1639  sc);
1640 }
1641 
1642 
1648 void
1650 {
1651  struct GNUNET_FS_ProgressInfo pi;
1652 
1653  GNUNET_assert (NULL == sc->mq);
1654  GNUNET_assert (NULL == sc->task);
1655  do_reconnect (sc);
1658  sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
1661 }
1662 
1663 
1672 static int
1674  const struct GNUNET_HashCode *key,
1675  void *value)
1676 {
1677  struct GNUNET_FS_SearchContext *sc = cls;
1678  struct GNUNET_FS_SearchResult *sr = value;
1679  struct GNUNET_FS_ProgressInfo pi;
1680 
1682  if (NULL != sr->download)
1683  {
1684  sr->download->search = NULL;
1685  sr->download->top
1686  = GNUNET_FS_make_top (sr->download->h,
1688  sr->download);
1689  if (NULL != sr->download->serialization)
1690  {
1693  sr->download->serialization);
1695  sr->download->serialization = NULL;
1696  }
1699  sr->download);
1701  sr->download = NULL;
1702  }
1703  if (0 != sr->mandatory_missing)
1704  {
1705  /* client is unaware of search result as
1706  it does not match required keywords */
1707  GNUNET_break (NULL == sr->client_info);
1708  return GNUNET_OK;
1709  }
1711  pi.value.search.specifics.result_stopped.cctx = sr->client_info;
1712  pi.value.search.specifics.result_stopped.meta = sr->meta;
1713  pi.value.search.specifics.result_stopped.uri = sr->uri;
1714  sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->h, sc);
1715  return GNUNET_OK;
1716 }
1717 
1718 
1727 static int
1729  const struct GNUNET_HashCode *key,
1730  void *value)
1731 {
1732  struct GNUNET_FS_SearchResult *sr = value;
1733 
1734  if (NULL != sr->update_search)
1735  {
1737  GNUNET_assert (NULL == sr->update_search);
1738  }
1739  GNUNET_break (NULL == sr->probe_ctx);
1740  GNUNET_break (NULL == sr->probe_cancel_task);
1741  GNUNET_break (NULL == sr->client_info);
1743  GNUNET_FS_uri_destroy (sr->uri);
1746  GNUNET_free (sr);
1747  return GNUNET_OK;
1748 }
1749 
1750 
1756 void
1758 {
1759  struct GNUNET_FS_ProgressInfo pi;
1760  unsigned int i;
1761 
1762  if (NULL != sc->top)
1763  GNUNET_FS_end_top (sc->h, sc->top);
1766  sc);
1767  if (NULL != sc->psearch_result)
1768  sc->psearch_result->update_search = NULL;
1769  if (NULL != sc->serialization)
1770  {
1772  (NULL != sc->psearch_result)
1775  sc->serialization);
1777  (NULL != sc->psearch_result)
1779  : GNUNET_FS_SYNC_PATH_MASTER_SEARCH,
1780  sc->serialization);
1781  GNUNET_free (sc->serialization);
1782  }
1785  sc->h,
1786  sc);
1787  GNUNET_break (NULL == sc->client_info);
1788  if (NULL != sc->task)
1789  {
1791  sc->task = NULL;
1792  }
1793  if (NULL != sc->mq)
1794  {
1795  GNUNET_MQ_destroy (sc->mq);
1796  sc->mq = NULL;
1797  }
1799  &search_result_free, sc);
1801  if (NULL != sc->requests)
1802  {
1804  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1806  }
1808  GNUNET_free_non_null (sc->emsg);
1809  GNUNET_FS_uri_destroy (sc->uri);
1810  GNUNET_free (sc);
1811 }
1812 
1813 /* end of fs_search.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void * client_info
Client info for this search result.
Definition: fs_api.h:548
uint32_t optional_support
Number of optional keywords under which this result was also found.
Definition: fs_api.h:616
int GNUNET_FS_uri_test_ksk(const struct GNUNET_FS_Uri *uri)
Is this a keyword URI?
Definition: fs_uri.c:1323
#define GNUNET_FS_VERSION
Version number of the implementation.
Notification that we have started this download.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_get_anonymous(void)
Get the shared private key we use for anonymous users.
Definition: crypto_ecc.c:814
Closure for build_result_set().
Definition: fs_search.c:999
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:104
void GNUNET_CRYPTO_ecdsa_public_key_derive(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, const char *context, struct GNUNET_CRYPTO_EcdsaPublicKey *result)
Derive a public key from a given public key and a label.
Definition: crypto_ecc.c:1339
struct GNUNET_SCHEDULER_Task * task
ID of a task that is using this struct and that must be cancelled when the search is being stopped (i...
Definition: fs_api.h:1606
static void start_probe_ping_task(struct GNUNET_FS_SearchResult *sr)
Start the ping task for this search result.
Definition: fs_search.c:386
struct GNUNET_FS_ProgressInfo::@28::@31 search
Values for all "GNUNET_FS_STATUS_SEARCH_*" events.
uint32_t mandatory_count
Number of mandatory keywords in this query.
Definition: fs_api.h:1616
static void signal_probe_result(struct GNUNET_FS_SearchResult *sr)
Signal result of last probe to client and then schedule next probe.
Definition: fs_search.c:194
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
struct GNUNET_FS_DownloadContext * download
ID of an associated download based on this search result (or NULL for none).
Definition: fs_api.h:560
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:215
uint64_t rel_value_us
The actual value.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
This search has yielded a result.
struct GNUNET_TIME_Relative avg_block_latency
Average time we take for a single request to be satisfied.
Definition: fs_api.h:1165
Last message from a search; this signals that there will be no further events associated with this se...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_FS_SearchResult * psearch_result
For update-searches, link to the search result that triggered the update search; otherwise NULL...
Definition: fs_api.h:1554
Any type of block, used as a wildcard when searching.
struct GNUNET_HashCode uquery
Hash of the public key, also known as the query.
Definition: fs_api.h:1498
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1774
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static void notify_client_chk_result(struct GNUNET_FS_SearchContext *sc, struct GNUNET_FS_SearchResult *sr)
We&#39;ve found a new CHK result.
Definition: fs_search.c:103
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:901
struct GNUNET_MessageHeader header
Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
Definition: fs.h:370
Notification that this download was suspended.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
static void schedule_transmit_search_request(struct GNUNET_FS_SearchContext *sc)
Schedule the transmission of the (next) search request to the service.
Definition: fs_search.c:1093
#define GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD
Name of the directory with downloads that are part of another download or a search.
Definition: fs_api.h:71
Event generated for each search result when the respective search is stopped.
struct GNUNET_FS_SearchContext * sc
Search context we are iterating for.
Definition: fs_search.c:1019
struct GNUNET_FS_Uri * GNUNET_FS_uri_parse(const char *uri, char **emsg)
Convert a UTF-8 String to a URI.
Definition: fs_uri.c:635
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_FS_search_continue(struct GNUNET_FS_SearchContext *sc)
Continue paused search.
Definition: fs_search.c:1649
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition: fs_api.c:1944
Master context for most FS operations.
Definition: fs_api.h:1087
enum GNUNET_FS_SearchOptions options
Options for the search.
Definition: fs_api.h:1621
void GNUNET_FS_search_sync_(struct GNUNET_FS_SearchContext *sc)
Synchronize this search struct with its mirror on disk.
Definition: fs_api.c:2135
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:279
struct GNUNET_CRYPTO_EcdsaPublicKey dpub
Derived public key, hashes to &#39;uquery&#39;.
Definition: fs_api.h:1503
struct TopLevelActivity * top
Our top-level activity entry (if we are top-level, otherwise NULL).
Definition: fs_api.h:1543
char * emsg
Error message (non-NULL if this operation failed).
Definition: fs_api.h:1574
struct GNUNET_TIME_Absolute start_time
When did we start?
Definition: fs_api.h:1593
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_FS_SearchContext * sc
Search context this result belongs to; can be NULL for probes that come from a directory result...
Definition: fs_api.h:533
uint8_t * keyword_bitmap
Bitmap that specifies precisely which keywords have been matched already.
Definition: fs_api.h:576
int mandatory
Is this keyword a mandatory keyword (started with &#39;+&#39;)?
Definition: fs_api.h:1525
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.
Definition: fs_download.c:106
uint32_t options
Bitmask with options.
Definition: fs.h:292
struct GNUNET_FS_ProgressInfo::@28::@30 download
Values for all "GNUNET_FS_STATUS_DOWNLOAD_*" events.
struct GNUNET_FS_SearchResult * GNUNET_FS_probe(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, void *client_info, uint32_t anonymity)
Start download probes for the given search result.
Definition: fs_search.c:483
void GNUNET_FS_ublock_decrypt_(const void *input, size_t input_len, const struct GNUNET_CRYPTO_EcdsaPublicKey *ns, const char *label, void *output)
Decrypt the given UBlock, storing the result in output.
GNUNET_FS_SearchOptions
Options for searching.
static void process_sblock(struct GNUNET_FS_SearchContext *sc, const struct UBlock *ub, size_t size)
Process a namespace-search result.
Definition: fs_search.c:861
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_deserialize(const char *input, size_t size)
Deserialize meta-data.
struct GNUNET_FS_Uri * uri
URI to which this search result refers to.
Definition: fs_api.h:538
First event generated when a client requests a search to begin or when a namespace result automatical...
static int test_result_present(void *cls, const struct GNUNET_HashCode *key, void *value)
Check if the given result is identical to the given URI.
Definition: fs_search.c:82
#define GNUNET_NO
Definition: gnunet_common.h:81
Context for "get_result_present".
Definition: fs_search.c:148
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static int get_result_present(void *cls, const struct GNUNET_HashCode *key, void *value)
Check if the given result is identical to the given URI and if so return it.
Definition: fs_search.c:174
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
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:1204
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
static int decrypt_block_with_keyword(const struct GNUNET_FS_SearchContext *sc, const struct GNUNET_CRYPTO_EcdsaPublicKey *dpub, const void *edata, size_t edata_size, char *data)
Decrypt a ublock using a &#39;keyword&#39; as the passphrase.
Definition: fs_search.c:746
struct GNUNET_FS_DownloadContext * probe_ctx
ID of a job that is currently probing this results&#39; availability (NULL if we are not currently probin...
Definition: fs_api.h:554
int GNUNET_FS_uri_test_sks(const struct GNUNET_FS_Uri *uri)
Is this a namespace URI?
Definition: fs_uri.c:1270
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int find_result_set(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterating over the known results, count those matching the given result range and increment put count...
Definition: fs_search.c:1071
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static void probe_failure_handler(void *cls)
Handle the case where we have failed to receive a response for our probe.
Definition: fs_search.c:220
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static int search_result_freeze_probes(void *cls, const struct GNUNET_HashCode *key, void *value)
Freeze probes for the given search result.
Definition: fs_search.c:1447
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:314
struct GNUNET_FS_DownloadContext * GNUNET_FS_download_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_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.
Definition: fs_download.c:2126
struct GNUNET_FS_Uri * GNUNET_FS_uri_dup(const struct GNUNET_FS_Uri *uri)
Duplicate URI.
Definition: fs_uri.c:988
static void process_kblock(struct GNUNET_FS_SearchContext *sc, const struct UBlock *ub, size_t size)
Process a keyword search result.
Definition: fs_search.c:789
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Type of a block representing a block to be encoded on demand from disk.
struct SearchRequestEntry * requests
Per-keyword information for a keyword search.
Definition: fs_api.h:1588
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
struct GNUNET_FS_Uri * uri
List of keywords that we&#39;re looking for.
Definition: fs_api.h:1548
static void do_reconnect(void *cls)
Reconnect to the FS service and transmit our queries NOW.
Definition: fs_search.c:1250
struct GNUNET_FS_SearchContext * update_search
If this search result triggered an update search, this field links to the update search.
Definition: fs_api.h:566
int GNUNET_FS_uri_to_key(const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode *key)
Get a unique key from a URI.
Definition: fs_uri.c:104
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
uint32_t anonymity
Anonymity level for the search.
Definition: fs_api.h:1611
struct GNUNET_HashCode query
Hash of the public key for UBLOCKs; Hash of the CHK-encoded block for DBLOCKS and IBLOCKS...
Definition: fs.h:320
Do not append temporary data to the target file (for the IBlocks).
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
struct GNUNET_TIME_AbsoluteNBO expiration
When does this result expire?
Definition: fs.h:380
unsigned int GNUNET_STRINGS_buffer_tokenize(const char *buffer, size_t size, unsigned int count,...)
Given a buffer of a given size, find "count" 0-terminated strings in the buffer and assign the count ...
Definition: strings.c:136
Meta data to associate with a file, directory or namespace.
static void process_ksk_result(struct GNUNET_FS_SearchContext *sc, struct SearchRequestEntry *ent, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta)
We have received a KSK result.
Definition: fs_search.c:558
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
Notification that this download completed.
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:1246
union GNUNET_FS_ProgressInfo::@28 value
Values that depend on the event type.
char * serialization
Name of the file on disk we use for persistence.
Definition: fs_api.h:1569
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...
Definition: fs_download.c:1953
struct GNUNET_TIME_Relative remaining_probe_time
How much longer should we run the current probe before giving up?
Definition: fs_api.h:598
void * GNUNET_FS_probe_stop(struct GNUNET_FS_SearchResult *sr)
Stop probe activity.
Definition: fs_search.c:533
char * serialization
Random portion of filename we use for syncing state of this download.
Definition: fs_api.h:1842
uint32_t availability_trials
Number of availability trials that we have performed for this search result.
Definition: fs_api.h:627
struct GNUNET_FS_SearchResult * sr
Where to store a pointer to the search result struct if we found a match.
Definition: fs_search.c:159
static char * value
Value of the record to add/remove.
void GNUNET_CONTAINER_meta_data_merge(struct GNUNET_CONTAINER_MetaData *md, const struct GNUNET_CONTAINER_MetaData *in)
Extend metadata.
struct GNUNET_TIME_Relative reconnect_backoff
How long to wait before we try to reconnect to FS service?
Definition: fs_api.h:1598
struct GNUNET_CONTAINER_MultiHashMap * master_result_map
Map that contains a struct GNUNET_FS_SearchResult for each result that was found in the search...
Definition: fs_api.h:1582
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
Information we store for each search result.
Definition: fs_api.h:511
struct GNUNET_FS_Handle * h
File-sharing context this result belongs to.
Definition: fs_api.h:517
struct GNUNET_FS_Uri::@16::@17 ksk
static void probe_success_handler(void *cls)
Handle the case where we have gotten a response for our probe.
Definition: fs_search.c:244
Should we automatically trigger probes for search results to determine availability? (will create GNUNET_FS_STATUS_SEARCH_UPDATE events).
void GNUNET_FS_end_top(struct GNUNET_FS_Handle *h, struct TopLevelActivity *top)
Destroy a top-level activity entry.
Definition: fs_api.c:416
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
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:1273
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_create(void)
Create a fresh meta data container.
enum GNUNET_FS_Status status
Specific status code (determines the event type).
uint32_t availability_success
Number of availability tests that have succeeded for this result.
Definition: fs_api.h:621
Internal option used to flag this download as a &#39;probe&#39; for a search result.
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
void GNUNET_FS_stop_probe_ping_task_(struct GNUNET_FS_SearchResult *sr)
Stop the ping task for this search result.
Definition: fs_search.c:406
union GNUNET_FS_Uri::@16 data
struct GNUNET_FS_SearchContext * GNUNET_FS_search_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, uint32_t anonymity, enum GNUNET_FS_SearchOptions options, void *cctx)
Start search for content.
Definition: fs_search.c:1598
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
Inner block in the CHK tree.
void GNUNET_FS_search_result_sync_(struct GNUNET_FS_SearchResult *sr)
Synchronize this search result with its mirror on disk.
Definition: fs_api.c:2048
#define GNUNET_FS_PROBE_UPDATE_FREQUENCY
How often do we signal applications that a probe for a particular search result is running...
void GNUNET_FS_download_stop(struct GNUNET_FS_DownloadContext *dc, int do_delete)
Stop a download (aborts if download is incomplete).
Definition: fs_download.c:2313
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
uint32_t type
Type of the content that we&#39;re looking for.
Definition: fs.h:297
void GNUNET_CONTAINER_meta_data_destroy(struct GNUNET_CONTAINER_MetaData *md)
Free meta data.
static void GNUNET_FS_search_stop_probe_(struct GNUNET_FS_SearchResult *sr)
Stop probing activity associated with a search result.
Definition: fs_search.c:509
struct GNUNET_CONTAINER_MultiHashMap * results
Map that contains a "struct GNUNET_FS_SearchResult" for each result that was found under this keyword...
Definition: fs_api.h:1519
static int search_result_free(void *cls, const struct GNUNET_HashCode *key, void *value)
Free the given search result.
Definition: fs_search.c:1728
static int result
Global testing status.
struct TopLevelActivity * top
Our top-level activity entry (if we are top-level, otherwise NULL).
Definition: fs_api.h:1779
struct GNUNET_TIME_Relative GNUNET_TIME_relative_subtract(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Subtract relative timestamp from the other.
Definition: time.c:601
uint32_t anonymity
Anonymity level to use for probes using this search result.
Definition: fs_api.h:603
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:670
unsigned int keyword_offset
Keyword offset the search result must match (0 for SKS)
Definition: fs_search.c:1024
Signals that this search was continued (unpaused).
Type of a block representing any type of search result (universal).
A 512-bit hashcode.
#define AVAILABILITY_TRIALS_MAX
Number of availability trials we perform per search result.
Definition: fs_search.c:36
Message handler for a specific message type.
#define GNUNET_FS_SYNC_PATH_CHILD_SEARCH
Name of the directory with sub-searches (namespace-updates).
Definition: fs_api.h:59
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
static void process_sks_result(struct GNUNET_FS_SearchContext *sc, const char *id_update, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta)
We have received an SKS result.
Definition: fs_search.c:678
Notification that this download is no longer actively being pursued (back in the queue).
Content-hash-key (simple file).
Definition: fs_api.h:146
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static int check_result(void *cls, const struct ClientPutMessage *cm)
We check a result message from the service.
Definition: fs_search.c:925
struct GNUNET_FS_SearchResult * search
Associated search (used when downloading files based on search results), or NULL for none...
Definition: fs_api.h:1796
Last event when a search is being suspended; note that "GNUNET_FS_SEARCH_STOPPED" will not be generat...
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
int GNUNET_FS_search_start_searching_(struct GNUNET_FS_SearchContext *sc)
Build the request and actually initiate the search using the GNUnet FS service.
Definition: fs_search.c:1387
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:241
Notification about progress with this download.
unsigned int put_cnt
How many entries can we store to xoff.
Definition: fs_search.c:1004
Notification that this download is now actively being pursued (as opposed to waiting in the queue)...
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:37
#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_CONTAINER_MetaData * meta
Metadata for the search result.
Definition: fs_api.h:543
Notification that this download is being resumed.
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:173
int 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.
struct GNUNET_HashCode key
Key for the search result based on the URI.
Definition: fs_api.h:581
static int search_result_resume_probes(void *cls, const struct GNUNET_HashCode *key, void *value)
Resume probes for the given search result.
Definition: fs_search.c:1479
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
#define GNUNET_MESSAGE_TYPE_FS_START_SEARCH
Client asks FS service to start a (keyword) search.
struct GNUNET_FS_Handle * fsh
File-sharing handle that generated the event.
const struct GNUNET_FS_Uri * uri
The URI we&#39;re looking for.
Definition: fs_search.c:153
struct TopLevelActivity * GNUNET_FS_make_top(struct GNUNET_FS_Handle *h, SuspendSignalFunction ssf, void *ssf_cls)
Create a top-level activity entry.
Definition: fs_api.c:393
Response from FS service with a result for a previous FS search.
Definition: fs.h:364
static void search_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...
Definition: fs_search.c:1229
Notification that this download is no longer part of a recursive download or search but now a &#39;stand-...
Allow multiple values with the same key.
uint32_t type
Type of the block (in big endian).
Definition: fs.h:375
Signed key space (file in namespace).
Definition: fs_api.h:151
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
struct GNUNET_HashCode * xoff
Where to store the keys.
Definition: fs_search.c:1014
#define GNUNET_FS_SYNC_PATH_MASTER_SEARCH
Name of the directory with top-level searches.
Definition: fs_api.h:54
struct GNUNET_FS_Uri::@16::@18 sks
The identity of the host (wraps the signing key of the peer).
uint32_t mandatory_missing
Number of mandatory keywords for which we have NOT yet found the search result; when this value hits ...
Definition: fs_api.h:610
Event generated for each search result when the respective search is suspended.
GNUNET_FS_ProgressCallback upcb
Function to call with updates on our progress.
Definition: fs_api.h:1102
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
struct GNUNET_FS_SearchResult * next
Kept in a DLL while probing.
Definition: fs_api.h:522
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:1359
shared definitions for the FS library
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:168
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:373
Handle for controlling a search.
Definition: fs_api.h:1533
struct GNUNET_SCHEDULER_Task * probe_ping_task
Task we use to report periodically to the application that certain search probes (from probes_head) a...
Definition: fs_api.h:1159
static struct GNUNET_CONTAINER_MetaData * meta
Meta-data provided via command-line option.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
void * upcb_cls
Closure for upcb.
Definition: fs_api.h:1107
static int search_result_suspend(void *cls, const struct GNUNET_HashCode *key, void *value)
Signal suspend and free the given search result.
Definition: fs_search.c:1501
static int search_result_stop(void *cls, const struct GNUNET_HashCode *key, void *value)
Signal stop for the given search result.
Definition: fs_search.c:1673
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1559
struct GNUNET_FS_Handle * h
Handle to the global FS context.
Definition: fs_api.h:1538
Only search the local host, do not search remote systems (no P2P)
Data block (leaf) in the CHK tree.
struct GNUNET_FS_SearchResult * probes_head
Head of active probes.
Definition: fs_api.h:1142
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
#define SEARCH_MESSAGE_OPTION_CONTINUED
Request is too large to fit in 64k format.
Definition: fs.h:268
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1784
Location (chk with identity of hosting peer).
Definition: fs_api.h:161
struct GNUNET_TIME_Absolute probe_active_time
When did the current probe become active?
Definition: fs_api.h:593
We have additional data about the quality or availability of a search result.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
void GNUNET_FS_search_pause(struct GNUNET_FS_SearchContext *sc)
Pause search.
Definition: fs_search.c:1618
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:80
static unsigned int anonymity
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:193
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:353
void * GNUNET_FS_search_make_status_(struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_Handle *h, struct GNUNET_FS_SearchContext *sc)
Fill in all of the generic fields for a search event and call the callback.
Definition: fs_search.c:48
char * serialization
Name under which this search result is stored on disk.
Definition: fs_api.h:571
static int update_sre_result_maps(void *cls, const struct GNUNET_HashCode *key, void *value)
Update the &#39;results&#39; map for the individual keywords with the results from the &#39;global&#39; result set...
Definition: fs_search.c:1359
#define SEARCH_MESSAGE_OPTION_NONE
No options.
Definition: fs.h:255
#define SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY
Only search the local datastore (no network)
Definition: fs.h:260
Information we keep for each keyword in a keyword search.
Definition: fs_api.h:1492
static void try_reconnect(struct GNUNET_FS_SearchContext *sc)
Shutdown any existing connection to the FS service and try to establish a fresh one (and then re-tran...
Definition: fs_search.c:1284
static struct GNUNET_FS_SearchContext * search_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, uint32_t anonymity, enum GNUNET_FS_SearchOptions options, void *cctx, struct GNUNET_FS_SearchResult *psearch)
Start search for content, internal API.
Definition: fs_search.c:1312
struct GNUNET_FS_SearchResult * probes_tail
Tail of active probes.
Definition: fs_api.h:1147
static int build_result_set(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterating over the known results, pick those matching the given result range and store their keys at ...
Definition: fs_search.c:1038
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
Notification that this download was stopped (final event with respect to this action).
static void notify_client_chk_update(struct GNUNET_FS_SearchContext *sc, struct GNUNET_FS_SearchResult *sr)
We&#39;ve found new information about an existing CHK result.
Definition: fs_search.c:125
Message sent from a GNUnet (fs) search activity to the gnunet-service-fs to start a search...
Definition: fs.h:275
uint32_t data
The data value.
Signals that this search was paused.
unsigned int skip_cnt
How many entries should we skip.
Definition: fs_search.c:1009
void * client_info
Pointer we keep for the client.
Definition: fs_api.h:1564
#define GNUNET_MESSAGE_TYPE_FS_PUT
P2P response with content or active migration of content.
uint32_t anonymity_level
Desired anonymity level, big-endian.
Definition: fs.h:302
char * keyword
The original keyword, used to derive the key (for decrypting the UBlock).
Definition: fs_api.h:1509
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition: time.c:499
void GNUNET_FS_search_signal_suspend_(void *cls)
Create SUSPEND event for the given search operation and then clean up our state (without stop signal)...
Definition: fs_search.c:1546
struct GNUNET_CRYPTO_EcdsaPublicKey verification_key
Public key used to sign this block.
Definition: block_fs.h:66
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
universal block for keyword and namespace search results
Definition: block_fs.h:50
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_malloc(size)
Wrapper around malloc.
void GNUNET_FS_search_stop(struct GNUNET_FS_SearchContext *sc)
Stop search for content.
Definition: fs_search.c:1757
void GNUNET_FS_search_start_probe_(struct GNUNET_FS_SearchResult *sr)
Start download probes for the given search result.
Definition: fs_search.c:427
void GNUNET_FS_remove_sync_file_(struct GNUNET_FS_Handle *h, const char *ext, const char *ent)
Remove serialization/deserialization file from disk.
Definition: fs_api.c:738
Notification that this download encountered an error.
static void probe_ping_task_cb(void *cls)
Task run periodically to remind clients that a probe is active.
Definition: fs_search.c:365
#define GNUNET_free(ptr)
Wrapper around free.
Argument given to the progress callback with information about what is going on.
Time for relative time used by GNUnet, in microseconds.
void * cctx
Client context pointer (set the last time by the client for this operation; initially NULL on START/R...
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static void handle_result(void *cls, const struct ClientPutMessage *cm)
We process a search result from the service.
Definition: fs_search.c:940
enum GNUNET_FS_Flags flags
General flags.
Definition: fs_api.h:1180
void GNUNET_FS_remove_sync_dir_(struct GNUNET_FS_Handle *h, const char *ext, const char *uni)
Remove serialization/deserialization directory from disk.
Definition: fs_api.c:797
struct GNUNET_SCHEDULER_Task * probe_cancel_task
ID of the task that will clean up the probe_ctx should it not complete on time (and that will need to...
Definition: fs_api.h:588
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
publish a UBLOCK in GNUnet
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_duplicate(const struct GNUNET_CONTAINER_MetaData *md)
Duplicate a MetaData token.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: fs_api.h:1092