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 
152  const struct GNUNET_FS_Uri *uri;
153 
159 };
160 
161 
172 static int
174  const struct GNUNET_HashCode *key,
175  void *value)
176 {
177  struct GetResultContext *grc = cls;
178  struct GNUNET_FS_SearchResult *sr = value;
179 
180  if (GNUNET_FS_uri_test_equal(grc->uri, sr->uri))
181  grc->sr = sr;
182  return GNUNET_OK;
183 }
184 
185 
192 static void
194 {
195  struct GNUNET_FS_ProgressInfo pi;
196 
198  pi.value.search.specifics.update.cctx = sr->client_info;
199  pi.value.search.specifics.update.meta = sr->meta;
200  pi.value.search.specifics.update.uri = sr->uri;
201  pi.value.search.specifics.update.availability_rank
203  pi.value.search.specifics.update.availability_certainty
204  = sr->availability_trials;
205  pi.value.search.specifics.update.applicability_rank = sr->optional_support;
206  pi.value.search.specifics.update.current_probe_time
208  sr->client_info = GNUNET_FS_search_make_status_(&pi, sr->h, sr->sc);
210 }
211 
212 
218 static void
220 {
221  struct GNUNET_FS_SearchResult *sr = cls;
222 
223  sr->probe_cancel_task = NULL;
224  sr->availability_trials++;
226  sr->probe_ctx = NULL;
230  "Probe #%u for search result %p failed\n",
232  sr);
234 }
235 
236 
242 static void
244 {
245  struct GNUNET_FS_SearchResult *sr = cls;
246 
247  sr->probe_cancel_task = NULL;
248  sr->availability_trials++;
249  sr->availability_success++;
251  sr->probe_ctx = NULL;
255  "Probe #%u for search result %p succeeded\n",
257  sr);
259 }
260 
261 
277 void *
279  const struct GNUNET_FS_ProgressInfo *info)
280 {
281  struct GNUNET_FS_SearchResult *sr = info->value.download.cctx;
282  struct GNUNET_TIME_Relative dur;
283 
284  switch (info->status)
285  {
287  /* ignore */
288  break;
289 
291  /* probes should never be resumed */
292  GNUNET_assert(0);
293  break;
294 
296  /* probes should never be suspended */
297  GNUNET_break(0);
298  break;
299 
301  /* ignore */
302  break;
303 
305  if (NULL != sr->probe_cancel_task)
306  {
308  sr->probe_cancel_task = NULL;
309  }
310  sr->probe_cancel_task =
312  &probe_failure_handler, sr);
313  break;
314 
316  if (NULL != sr->probe_cancel_task)
317  {
319  sr->probe_cancel_task = NULL;
320  }
321  sr->probe_cancel_task =
323  break;
324 
326  if (NULL != sr->probe_cancel_task)
327  {
329  sr->probe_cancel_task = NULL;
330  }
331  sr = NULL;
332  break;
333 
335  if (NULL == sr->probe_cancel_task)
336  {
338  sr->probe_cancel_task =
340  &probe_failure_handler, sr);
341  }
342  break;
343 
345  if (NULL != sr->probe_cancel_task)
346  {
348  sr->probe_cancel_task = NULL;
349  }
353  if (0 == sr->remaining_probe_time.rel_value_us)
354  sr->probe_cancel_task =
357  break;
358 
359  default:
360  GNUNET_break(0);
361  return NULL;
362  }
363  return sr;
364 }
365 
366 
372 static void
374 {
375  struct GNUNET_FS_Handle *h = cls;
376  struct GNUNET_FS_SearchResult *sr;
377 
378  for (sr = h->probes_head; NULL != sr; sr = sr->next)
379  if (NULL != sr->probe_ctx->mq)
381  h->probe_ping_task
384  h);
385 }
386 
387 
393 static void
395 {
396  struct GNUNET_FS_Handle *h = sr->h;
397 
399  h->probes_tail,
400  sr);
401  if (NULL == h->probe_ping_task)
402  h->probe_ping_task
404  h);
405 }
406 
407 
413 void
415 {
416  struct GNUNET_FS_Handle *h = sr->h;
417 
419  h->probes_tail,
420  sr);
421  if (NULL == h->probes_head)
422  {
424  h->probe_ping_task = NULL;
425  }
426 }
427 
428 
434 void
436 {
437  uint64_t off;
438  uint64_t len;
439 
440  if (NULL != sr->probe_ctx)
441  return;
442  if (NULL != sr->download)
443  return;
444  if (0 == (sr->h->flags & GNUNET_FS_FLAGS_DO_PROBES))
445  return;
447  return;
448  if ((GNUNET_FS_URI_CHK != sr->uri->type) && (GNUNET_FS_URI_LOC != sr->uri->type))
449  return;
451  if (0 == len)
452  return;
453  if ((len <= DBLOCK_SIZE) && (sr->availability_success > 0))
454  return;
455  off = len / DBLOCK_SIZE;
456  if (off > 0)
458  off *= DBLOCK_SIZE;
459  if (len - off < DBLOCK_SIZE)
460  len = len - off;
461  else
462  len = DBLOCK_SIZE;
464  "Starting probe #%u (at offset %llu) for search result %p\n",
465  sr->availability_trials + 1,
466  (unsigned long long)off,
467  sr);
470  2 * (1 + sr->availability_trials));
471  sr->probe_ctx =
472  GNUNET_FS_download_start(sr->h, sr->uri, sr->meta, NULL, NULL, off,
473  len, sr->anonymity,
475  GNUNET_FS_DOWNLOAD_IS_PROBE, sr, NULL);
477 }
478 
479 
490 struct GNUNET_FS_SearchResult *
492  const struct GNUNET_FS_Uri *uri,
493  const struct GNUNET_CONTAINER_MetaData *meta,
494  void *client_info,
495  uint32_t anonymity)
496 {
497  struct GNUNET_FS_SearchResult *sr;
498 
499  GNUNET_assert(NULL != h);
500  GNUNET_assert(NULL != uri);
501  sr = GNUNET_new(struct GNUNET_FS_SearchResult);
502  sr->h = h;
503  sr->uri = GNUNET_FS_uri_dup(uri);
505  sr->client_info = client_info;
506  sr->anonymity = anonymity;
508  return sr;
509 }
510 
511 
517 static void
519 {
520  if (NULL != sr->probe_ctx)
521  {
523  sr->probe_ctx = NULL;
525  }
526  if (NULL != sr->probe_cancel_task)
527  {
529  sr->probe_cancel_task = NULL;
530  }
531 }
532 
533 
541 void *
543 {
544  void *client_info;
545 
546  GNUNET_assert(NULL == sr->sc);
550  client_info = sr->client_info;
551  GNUNET_free(sr);
552  return client_info;
553 }
554 
555 
566 static void
568  struct SearchRequestEntry *ent,
569  const struct GNUNET_FS_Uri *uri,
570  const struct GNUNET_CONTAINER_MetaData *meta)
571 {
572  struct GNUNET_HashCode key;
573  struct GNUNET_FS_SearchResult *sr;
574  struct GetResultContext grc;
575  int is_new;
576  unsigned int koff;
577 
578  /* check if new */
579  GNUNET_assert(NULL != sc);
580  if (GNUNET_OK !=
582  &key))
583  {
584  GNUNET_break_op(0);
585  return;
586  }
587  if (GNUNET_SYSERR ==
589  &key,
591  (void *)uri))
592  return; /* duplicate result */
593  /* try to find search result in master map */
594  grc.sr = NULL;
595  grc.uri = uri;
597  &key,
598  &get_result_present, &grc);
599  sr = grc.sr;
600  is_new = (NULL == sr) || (sr->mandatory_missing > 0);
601  if (NULL == sr)
602  {
603  sr = GNUNET_new(struct GNUNET_FS_SearchResult);
604  sr->h = sc->h;
605  sr->sc = sc;
606  sr->anonymity = sc->anonymity;
607  sr->uri = GNUNET_FS_uri_dup(uri);
610  sr->key = key;
611  sr->keyword_bitmap = GNUNET_malloc((sc->uri->data.ksk.keywordCount + 7) / 8); /* round up, count bits */
614  }
615  else
616  {
618  }
621  &sr->key,
622  sr,
624 
625  koff = ent - sc->requests;
626  GNUNET_assert((ent >= sc->requests) &&
627  (koff < sc->uri->data.ksk.keywordCount));
628  sr->keyword_bitmap[koff / 8] |= (1 << (koff % 8));
629  /* check if mandatory satisfied */
631  {
632  if (ent->mandatory)
633  {
635  sr->mandatory_missing--;
636  }
637  else
638  {
639  sr->optional_support++;
640  }
641  }
642  if (0 != sr->mandatory_missing)
643  {
644  GNUNET_break(NULL == sr->client_info);
645  return;
646  }
647  if (is_new)
648  notify_client_chk_result(sc, sr);
649  else
650  notify_client_chk_update(sc, sr);
653 }
654 
655 
668 static struct GNUNET_FS_SearchContext *
670  const struct GNUNET_FS_Uri *uri,
671  uint32_t anonymity,
673  void *cctx,
674  struct GNUNET_FS_SearchResult *psearch);
675 
676 
686 static void
688  const char *id_update,
689  const struct GNUNET_FS_Uri *uri,
690  const struct GNUNET_CONTAINER_MetaData *meta)
691 {
692  struct GNUNET_FS_Uri uu;
693  struct GNUNET_HashCode key;
694  struct GNUNET_FS_SearchResult *sr;
695 
696  /* check if new */
697  GNUNET_assert(NULL != sc);
698  if (GNUNET_OK !=
700  &key))
701  {
702  GNUNET_break(0);
703  return;
704  }
706  &uri->data.chk.chk.query,
707  &key);
708  if (GNUNET_SYSERR ==
711  (void *)uri))
712  return; /* duplicate result */
713  sr = GNUNET_new(struct GNUNET_FS_SearchResult);
714  sr->h = sc->h;
715  sr->sc = sc;
716  sr->anonymity = sc->anonymity;
717  sr->uri = GNUNET_FS_uri_dup(uri);
719  sr->key = key;
724  /* notify client */
725  if (0 == sr->mandatory_missing)
726  notify_client_chk_result(sc, sr);
727  else
728  GNUNET_break(NULL == sr->client_info);
729  /* search for updates */
730  if (0 == strlen(id_update))
731  return; /* no updates */
732  uu.type = GNUNET_FS_URI_SKS;
733  uu.data.sks.ns = sc->uri->data.sks.ns;
734  uu.data.sks.identifier = GNUNET_strdup(id_update);
735  (void)search_start(sc->h, &uu, sc->anonymity, sc->options, NULL, sr);
736  GNUNET_free(uu.data.sks.identifier);
737 }
738 
739 
754 static int
756  const struct GNUNET_CRYPTO_EcdsaPublicKey *dpub,
757  const void *edata,
758  size_t edata_size,
759  char *data)
760 {
761  const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon;
762  struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
763  unsigned int i;
764 
765  /* find key */
766  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
767  if (0 == memcmp(dpub,
768  &sc->requests[i].dpub,
769  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
770  break;
771  if (i == sc->uri->data.ksk.keywordCount)
772  {
773  /* oops, does not match any of our keywords!? */
774  GNUNET_break(0);
775  return GNUNET_SYSERR;
776  }
777  /* decrypt */
779  GNUNET_CRYPTO_ecdsa_key_get_public(anon, &anon_pub);
780  GNUNET_FS_ublock_decrypt_(edata, edata_size,
781  &anon_pub,
782  sc->requests[i].keyword,
783  data);
784  return i;
785 }
786 
787 
797 static void
799  const struct UBlock *ub,
800  size_t size)
801 {
802  size_t j;
803  char pt[size - sizeof(struct UBlock)];
804  const char *eos;
806  struct GNUNET_FS_Uri *uri;
807  char *emsg;
808  int i;
809 
810  if (-1 == (i = decrypt_block_with_keyword(sc,
811  &ub->verification_key,
812  &ub[1],
813  size - sizeof(struct UBlock),
814  pt)))
815  return;
816  /* parse; pt[0] is just '\0', so we skip over that */
817  eos = memchr(&pt[1], '\0', sizeof(pt) - 1);
818  if (NULL == eos)
819  {
820  GNUNET_break_op(0);
821  return;
822  }
823  if (NULL == (uri = GNUNET_FS_uri_parse(&pt[1], &emsg)))
824  {
825  if (GNUNET_FS_VERSION > 0x00090400)
826  {
827  /* we broke this in 0x00090300, so don't bitch
828  too loudly just one version up... */
829  GNUNET_break_op(0); /* ublock malformed */
831  _("Failed to parse URI `%s': %s\n"),
832  &pt[1],
833  emsg);
834  }
835  GNUNET_free_non_null(emsg);
836  return;
837  }
838  j = eos - pt + 1;
839  if (sizeof(pt) == j)
841  else
842  meta = GNUNET_CONTAINER_meta_data_deserialize(&pt[j], sizeof(pt) - j);
843  if (NULL == meta)
844  {
845  GNUNET_break_op(0); /* ublock malformed */
847  return;
848  }
850  &sc->requests[i],
851  uri,
852  meta);
853 
854  /* clean up */
857 }
858 
859 
869 static void
871  const struct UBlock *ub,
872  size_t size)
873 {
874  size_t len = size - sizeof(struct UBlock);
875  char pt[len];
876  struct GNUNET_FS_Uri *uri;
878  const char *id;
879  const char *uris;
880  size_t off;
881  char *emsg;
882 
883  GNUNET_FS_ublock_decrypt_(&ub[1], len,
884  &sc->uri->data.sks.ns,
885  sc->uri->data.sks.identifier,
886  pt);
887  /* parse */
888  if (0 == (off = GNUNET_STRINGS_buffer_tokenize(pt, len, 2, &id, &uris)))
889  {
890  GNUNET_break_op(0); /* ublock malformed */
891  return;
892  }
893  if (NULL == (meta = GNUNET_CONTAINER_meta_data_deserialize(&pt[off], len - off)))
894  {
895  GNUNET_break_op(0); /* ublock malformed */
896  return;
897  }
898  if (NULL == (uri = GNUNET_FS_uri_parse(uris, &emsg)))
899  {
901  _("Failed to parse URI `%s': %s\n"),
902  uris, emsg);
903  GNUNET_break_op(0); /* ublock malformed */
904  GNUNET_free_non_null(emsg);
906  return;
907  }
908  /* process */
909  process_sks_result(sc, id, uri, meta);
910  /* clean up */
913 }
914 
915 
923 static void
925 
926 
933 static int
934 check_result(void *cls,
935  const struct ClientPutMessage *cm)
936 {
937  /* payload of any variable size is OK */
938  return GNUNET_OK;
939 }
940 
941 
948 static void
949 handle_result(void *cls,
950  const struct ClientPutMessage *cm)
951 {
952  struct GNUNET_FS_SearchContext *sc = cls;
953  uint16_t msize = ntohs(cm->header.size) - sizeof(*cm);
954  enum GNUNET_BLOCK_Type type = ntohl(cm->type);
955 
957  {
959  "Result received has already expired.\n");
960  return; /* result expired */
961  }
962  switch (type)
963  {
965  if (GNUNET_FS_URI_SKS == sc->uri->type)
966  process_sblock(sc,
967  (const struct UBlock *)&cm[1],
968  msize);
969  else
970  process_kblock(sc,
971  (const struct UBlock *)&cm[1],
972  msize);
973  break;
974 
976  GNUNET_break(0);
977  break;
978 
980  GNUNET_break(0);
981  break;
982 
984  GNUNET_break(0);
985  break;
986 
988  GNUNET_break(0);
989  break;
990 
991  default:
993  _("Got result with unknown block type `%d', ignoring"),
994  type);
995  break;
996  }
997 }
998 
999 
1006 static void
1008 
1009 
1017  unsigned int put_cnt;
1018 
1022  unsigned int skip_cnt;
1023 
1028 
1033 
1037  unsigned int keyword_offset;
1038 };
1039 
1040 
1050 static int
1052  const struct GNUNET_HashCode *key,
1053  void *value)
1054 {
1055  struct MessageBuilderContext *mbc = cls;
1056  struct GNUNET_FS_SearchResult *sr = value;
1057 
1058  if ((NULL != sr->keyword_bitmap) &&
1059  (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))))
1060  return GNUNET_OK; /* have no match for this keyword yet */
1061  if (mbc->skip_cnt > 0)
1062  {
1063  mbc->skip_cnt--;
1064  return GNUNET_OK;
1065  }
1066  if (0 == mbc->put_cnt)
1067  return GNUNET_SYSERR;
1068  mbc->xoff[--mbc->put_cnt] = *key;
1069 
1070  return GNUNET_OK;
1071 }
1072 
1073 
1083 static int
1085  const struct GNUNET_HashCode *key,
1086  void *value)
1087 {
1088  struct MessageBuilderContext *mbc = cls;
1089  struct GNUNET_FS_SearchResult *sr = value;
1090 
1091  if ((NULL != sr->keyword_bitmap) &&
1092  (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))))
1093  return GNUNET_OK; /* have no match for this keyword yet */
1094  mbc->put_cnt++;
1095  return GNUNET_OK;
1096 }
1097 
1098 
1105 static void
1107 {
1108  struct MessageBuilderContext mbc;
1109  struct GNUNET_MQ_Envelope *env;
1110  struct SearchMessage *sm;
1111  struct GNUNET_CRYPTO_EcdsaPublicKey dpub;
1112  unsigned int total_seen_results; /* total number of result hashes to send */
1113  uint32_t options;
1114  unsigned int left;
1115  unsigned int todo;
1116  unsigned int fit;
1117  unsigned int search_request_map_offset;
1118  unsigned int keyword_offset;
1119  int first_call;
1120 
1121  memset(&mbc, 0, sizeof(mbc));
1122  mbc.sc = sc;
1123  if (GNUNET_FS_uri_test_ksk(sc->uri))
1124  {
1125  /* This will calculate the result set size ONLY for
1126  "keyword_offset == 0", so we will have to recalculate
1127  it for the other keywords later! */
1129  &find_result_set,
1130  &mbc);
1131  total_seen_results = mbc.put_cnt;
1132  }
1133  else
1134  {
1135  total_seen_results
1137  }
1138  search_request_map_offset = 0;
1139  keyword_offset = 0;
1140  first_call = GNUNET_YES;
1141  while ((0 != (left =
1142  (total_seen_results - search_request_map_offset))) ||
1143  (GNUNET_YES == first_call))
1144  {
1145  first_call = GNUNET_NO;
1146  options = SEARCH_MESSAGE_OPTION_NONE;
1149 
1150  fit = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof(*sm)) / sizeof(struct GNUNET_HashCode);
1151  todo = GNUNET_MIN(fit,
1152  left);
1153  env = GNUNET_MQ_msg_extra(sm,
1154  sizeof(struct GNUNET_HashCode) * todo,
1156  mbc.skip_cnt = search_request_map_offset;
1157  mbc.xoff = (struct GNUNET_HashCode *)&sm[1];
1158  sm->type = htonl(GNUNET_BLOCK_TYPE_FS_UBLOCK);
1159  sm->anonymity_level = htonl(sc->anonymity);
1160  memset(&sm->target,
1161  0,
1162  sizeof(struct GNUNET_PeerIdentity));
1163 
1164  if (GNUNET_FS_uri_test_ksk(sc->uri))
1165  {
1166  mbc.keyword_offset = keyword_offset;
1167  /* calculate how many results we can send in this message */
1168  mbc.put_cnt = todo;
1169  /* now build message */
1170  sm->query = sc->requests[keyword_offset].uquery;
1173  &mbc);
1174  search_request_map_offset += todo;
1175  GNUNET_assert(0 == mbc.put_cnt);
1176  GNUNET_assert(total_seen_results >= search_request_map_offset);
1177  if (total_seen_results != search_request_map_offset)
1178  {
1179  /* more requesting to be done... */
1180  sm->options = htonl(options | SEARCH_MESSAGE_OPTION_CONTINUED);
1181  }
1182  else
1183  {
1184  sm->options = htonl(options);
1185  keyword_offset++;
1186  if (sc->uri->data.ksk.keywordCount != keyword_offset)
1187  {
1188  /* more keywords => more requesting to be done... */
1189  first_call = GNUNET_YES;
1190  search_request_map_offset = 0;
1191  mbc.put_cnt = 0;
1192  mbc.keyword_offset = keyword_offset;
1194  &find_result_set,
1195  &mbc);
1196  total_seen_results = mbc.put_cnt;
1197  }
1198  }
1199  }
1200  else
1201  {
1203 
1205  sc->uri->data.sks.identifier,
1206  "fs-ublock",
1207  &dpub);
1208  GNUNET_CRYPTO_hash(&dpub,
1209  sizeof(dpub),
1210  &sm->query);
1211  mbc.put_cnt = todo;
1212  mbc.keyword_offset = 0;
1215  &mbc);
1216  GNUNET_assert(total_seen_results >= search_request_map_offset);
1217  if (total_seen_results != search_request_map_offset)
1218  {
1219  /* more requesting to be done... */
1220  sm->options = htonl(options | SEARCH_MESSAGE_OPTION_CONTINUED);
1221  }
1222  else
1223  {
1224  sm->options = htonl(options);
1225  }
1226  }
1227  GNUNET_MQ_send(sc->mq,
1228  env);
1229  }
1230 }
1231 
1232 
1241 static void
1243  enum GNUNET_MQ_Error error)
1244 {
1245  struct GNUNET_FS_SearchContext *sc = cls;
1246 
1247  if (NULL != sc->mq)
1248  {
1249  GNUNET_MQ_destroy(sc->mq);
1250  sc->mq = NULL;
1251  }
1252  try_reconnect(sc);
1253 }
1254 
1255 
1262 static void
1263 do_reconnect(void *cls)
1264 {
1265  struct GNUNET_FS_SearchContext *sc = cls;
1266  struct GNUNET_MQ_MessageHandler handlers[] = {
1269  struct ClientPutMessage,
1270  sc),
1272  };
1273 
1274  sc->task = NULL;
1275  sc->mq = GNUNET_CLIENT_connect(sc->h->cfg,
1276  "fs",
1277  handlers,
1279  sc);
1280  if (NULL == sc->mq)
1281  {
1282  try_reconnect(sc);
1283  return;
1284  }
1286 }
1287 
1288 
1296 static void
1298 {
1299  if (NULL != sc->mq)
1300  {
1301  GNUNET_MQ_destroy(sc->mq);
1302  sc->mq = NULL;
1303  }
1305  sc->task =
1307  &do_reconnect,
1308  sc);
1309 }
1310 
1311 
1324 static struct GNUNET_FS_SearchContext *
1326  const struct GNUNET_FS_Uri *uri,
1327  uint32_t anonymity,
1329  void *cctx,
1330  struct GNUNET_FS_SearchResult *psearch)
1331 {
1332  struct GNUNET_FS_SearchContext *sc;
1333  struct GNUNET_FS_ProgressInfo pi;
1334 
1335  sc = GNUNET_new(struct GNUNET_FS_SearchContext);
1336  sc->h = h;
1337  sc->options = options;
1338  sc->uri = GNUNET_FS_uri_dup(uri);
1339  sc->anonymity = anonymity;
1340  sc->start_time = GNUNET_TIME_absolute_get();
1341  if (NULL != psearch)
1342  {
1343  sc->psearch_result = psearch;
1344  psearch->update_search = sc;
1345  }
1347  sc->client_info = cctx;
1349  {
1350  GNUNET_FS_uri_destroy(sc->uri);
1351  GNUNET_CONTAINER_multihashmap_destroy(sc->master_result_map);
1352  GNUNET_free(sc);
1353  return NULL;
1354  }
1357  sc->client_info = GNUNET_FS_search_make_status_(&pi, sc->h, sc);
1358  return sc;
1359 }
1360 
1361 
1371 static int
1373  const struct GNUNET_HashCode *key,
1374  void *value)
1375 {
1376  struct GNUNET_FS_SearchContext *sc = cls;
1377  struct GNUNET_FS_SearchResult *sr = value;
1378  unsigned int i;
1379 
1380  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1381  if (0 != (sr->keyword_bitmap[i / 8] & (1 << (i % 8))))
1384  &sr->key,
1385  sr,
1387 
1388  return GNUNET_YES;
1389 }
1390 
1391 
1399 int
1401 {
1402  unsigned int i;
1403  const char *keyword;
1404  const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon;
1405  struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
1406  struct SearchRequestEntry *sre;
1407 
1408  GNUNET_assert(NULL == sc->mq);
1409  if (GNUNET_FS_uri_test_ksk(sc->uri))
1410  {
1411  GNUNET_assert(0 != sc->uri->data.ksk.keywordCount);
1413  GNUNET_CRYPTO_ecdsa_key_get_public(anon, &anon_pub);
1414  sc->requests
1415  = GNUNET_new_array(sc->uri->data.ksk.keywordCount,
1416  struct SearchRequestEntry);
1417 
1418  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1419  {
1420  keyword = &sc->uri->data.ksk.keywords[i][1];
1421  sre = &sc->requests[i];
1422  sre->keyword = GNUNET_strdup(keyword);
1424  keyword,
1425  "fs-ublock",
1426  &sre->dpub);
1427  GNUNET_CRYPTO_hash(&sre->dpub,
1428  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
1429  &sre->uquery);
1430  sre->mandatory = (sc->uri->data.ksk.keywords[i][0] == '+');
1431  if (sre->mandatory)
1432  sc->mandatory_count++;
1434  }
1437  sc);
1438  }
1439  GNUNET_assert(NULL == sc->task);
1440  do_reconnect(sc);
1441  if (NULL == sc->mq)
1442  {
1444  sc->task = NULL;
1445  return GNUNET_SYSERR;
1446  }
1447  return GNUNET_OK;
1448 }
1449 
1450 
1459 static int
1461  const struct GNUNET_HashCode *key,
1462  void *value)
1463 {
1464  struct GNUNET_FS_SearchResult *sr = value;
1465 
1466  if (NULL != sr->probe_ctx)
1467  {
1469  sr->probe_ctx = NULL;
1471  }
1472  if (NULL != sr->probe_cancel_task)
1473  {
1475  sr->probe_cancel_task = NULL;
1476  }
1477  if (NULL != sr->update_search)
1479  return GNUNET_OK;
1480 }
1481 
1482 
1491 static int
1493  const struct GNUNET_HashCode * key,
1494  void *value)
1495 {
1496  struct GNUNET_FS_SearchResult *sr = value;
1497 
1499  if (NULL != sr->update_search)
1501  return GNUNET_OK;
1502 }
1503 
1504 
1513 static int
1515  const struct GNUNET_HashCode *key,
1516  void *value)
1517 {
1518  struct GNUNET_FS_SearchContext *sc = cls;
1519  struct GNUNET_FS_SearchResult *sr = value;
1520  struct GNUNET_FS_ProgressInfo pi;
1521 
1522  if (NULL != sr->download)
1523  {
1525  sr->download = NULL;
1526  }
1527  if (NULL != sr->update_search)
1528  {
1530  sr->update_search = NULL;
1531  }
1533  if (0 == sr->mandatory_missing)
1534  {
1535  /* client is aware of search result, notify about suspension event */
1537  pi.value.search.specifics.result_suspend.cctx = sr->client_info;
1538  pi.value.search.specifics.result_suspend.meta = sr->meta;
1539  pi.value.search.specifics.result_suspend.uri = sr->uri;
1540  sr->client_info = GNUNET_FS_search_make_status_(&pi, sc->h, sc);
1541  }
1542  GNUNET_break(NULL == sr->client_info);
1547  GNUNET_free(sr);
1548  return GNUNET_OK;
1549 }
1550 
1551 
1558 void
1560 {
1561  struct GNUNET_FS_SearchContext *sc = cls;
1562  struct GNUNET_FS_ProgressInfo pi;
1563  unsigned int i;
1564 
1565  GNUNET_FS_end_top(sc->h, sc->top);
1567  &search_result_suspend, sc);
1569  sc->client_info = GNUNET_FS_search_make_status_(&pi, sc->h, sc);
1570  GNUNET_break(NULL == sc->client_info);
1571  if (sc->task != NULL)
1572  {
1574  sc->task = NULL;
1575  }
1576  if (NULL != sc->mq)
1577  {
1578  GNUNET_MQ_destroy(sc->mq);
1579  sc->mq = NULL;
1580  }
1582  if (NULL != sc->requests)
1583  {
1585  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1586  {
1588  GNUNET_free(sc->requests[i].keyword);
1589  }
1590  }
1595  GNUNET_free(sc);
1596 }
1597 
1598 
1610 struct GNUNET_FS_SearchContext *
1612  const struct GNUNET_FS_Uri *uri, uint32_t anonymity,
1613  enum GNUNET_FS_SearchOptions options, void *cctx)
1614 {
1615  struct GNUNET_FS_SearchContext *ret;
1616 
1617  ret = search_start(h, uri, anonymity, options, cctx, NULL);
1618  if (NULL == ret)
1619  return NULL;
1621  return ret;
1622 }
1623 
1624 
1630 void
1632 {
1633  struct GNUNET_FS_ProgressInfo pi;
1634 
1635  if (NULL != sc->task)
1636  {
1638  sc->task = NULL;
1639  }
1640  if (NULL != sc->mq)
1641  {
1642  GNUNET_MQ_destroy(sc->mq);
1643  sc->mq = NULL;
1644  }
1648  sc);
1651  sc->h,
1652  sc);
1653 }
1654 
1655 
1661 void
1663 {
1664  struct GNUNET_FS_ProgressInfo pi;
1665 
1666  GNUNET_assert(NULL == sc->mq);
1667  GNUNET_assert(NULL == sc->task);
1668  do_reconnect(sc);
1671  sc->client_info = GNUNET_FS_search_make_status_(&pi, sc->h, sc);
1674 }
1675 
1676 
1685 static int
1687  const struct GNUNET_HashCode *key,
1688  void *value)
1689 {
1690  struct GNUNET_FS_SearchContext *sc = cls;
1691  struct GNUNET_FS_SearchResult *sr = value;
1692  struct GNUNET_FS_ProgressInfo pi;
1693 
1695  if (NULL != sr->download)
1696  {
1697  sr->download->search = NULL;
1698  sr->download->top
1699  = GNUNET_FS_make_top(sr->download->h,
1701  sr->download);
1702  if (NULL != sr->download->serialization)
1703  {
1706  sr->download->serialization);
1708  sr->download->serialization = NULL;
1709  }
1712  sr->download);
1714  sr->download = NULL;
1715  }
1716  if (0 != sr->mandatory_missing)
1717  {
1718  /* client is unaware of search result as
1719  it does not match required keywords */
1720  GNUNET_break(NULL == sr->client_info);
1721  return GNUNET_OK;
1722  }
1724  pi.value.search.specifics.result_stopped.cctx = sr->client_info;
1725  pi.value.search.specifics.result_stopped.meta = sr->meta;
1726  pi.value.search.specifics.result_stopped.uri = sr->uri;
1727  sr->client_info = GNUNET_FS_search_make_status_(&pi, sr->h, sc);
1728  return GNUNET_OK;
1729 }
1730 
1731 
1740 static int
1742  const struct GNUNET_HashCode *key,
1743  void *value)
1744 {
1745  struct GNUNET_FS_SearchResult *sr = value;
1746 
1747  if (NULL != sr->update_search)
1748  {
1750  GNUNET_assert(NULL == sr->update_search);
1751  }
1752  GNUNET_break(NULL == sr->probe_ctx);
1753  GNUNET_break(NULL == sr->probe_cancel_task);
1754  GNUNET_break(NULL == sr->client_info);
1759  GNUNET_free(sr);
1760  return GNUNET_OK;
1761 }
1762 
1763 
1769 void
1771 {
1772  struct GNUNET_FS_ProgressInfo pi;
1773  unsigned int i;
1774 
1775  if (NULL != sc->top)
1776  GNUNET_FS_end_top(sc->h, sc->top);
1779  sc);
1780  if (NULL != sc->psearch_result)
1781  sc->psearch_result->update_search = NULL;
1782  if (NULL != sc->serialization)
1783  {
1785  (NULL != sc->psearch_result)
1788  sc->serialization);
1790  (NULL != sc->psearch_result)
1792  : GNUNET_FS_SYNC_PATH_MASTER_SEARCH,
1793  sc->serialization);
1795  }
1798  sc->h,
1799  sc);
1800  GNUNET_break(NULL == sc->client_info);
1801  if (NULL != sc->task)
1802  {
1804  sc->task = NULL;
1805  }
1806  if (NULL != sc->mq)
1807  {
1808  GNUNET_MQ_destroy(sc->mq);
1809  sc->mq = NULL;
1810  }
1812  &search_result_free, sc);
1814  if (NULL != sc->requests)
1815  {
1817  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1819  }
1823  GNUNET_free(sc);
1824 }
1825 
1826 /* 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:519
uint32_t optional_support
Number of optional keywords under which this result was also found.
Definition: fs_api.h:587
int GNUNET_FS_uri_test_ksk(const struct GNUNET_FS_Uri *uri)
Is this a keyword URI?
Definition: fs_uri.c:1332
#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:1013
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:102
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:1340
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:1564
static void start_probe_ping_task(struct GNUNET_FS_SearchResult *sr)
Start the ping task for this search result.
Definition: fs_search.c:394
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:1574
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:193
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:671
struct GNUNET_FS_DownloadContext * download
ID of an associated download based on this search result (or NULL for none).
Definition: fs_api.h:531
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:204
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:1133
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:1512
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:1458
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1726
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:900
struct GNUNET_MessageHeader header
Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
Definition: fs.h:350
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:1106
#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:1032
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:641
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:1662
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition: fs_api.c:1971
Master context for most FS operations.
Definition: fs_api.h:1056
enum GNUNET_FS_SearchOptions options
Options for the search.
Definition: fs_api.h:1579
void GNUNET_FS_search_sync_(struct GNUNET_FS_SearchContext *sc)
Synchronize this search struct with its mirror on disk.
Definition: fs_api.c:2166
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:278
struct GNUNET_CRYPTO_EcdsaPublicKey dpub
Derived public key, hashes to &#39;uquery&#39;.
Definition: fs_api.h:1463
struct TopLevelActivity * top
Our top-level activity entry (if we are top-level, otherwise NULL).
Definition: fs_api.h:1501
char * emsg
Error message (non-NULL if this operation failed).
Definition: fs_api.h:1532
struct GNUNET_TIME_Absolute start_time
When did we start?
Definition: fs_api.h:1551
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:504
uint8_t * keyword_bitmap
Bitmap that specifies precisely which keywords have been matched already.
Definition: fs_api.h:547
int mandatory
Is this keyword a mandatory keyword (started with &#39;+&#39;)?
Definition: fs_api.h:1485
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:103
uint32_t options
Bitmask with options.
Definition: fs.h:277
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:491
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:870
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:509
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:78
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:75
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:173
#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:1209
#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:755
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:525
int GNUNET_FS_uri_test_sks(const struct GNUNET_FS_Uri *uri)
Is this a namespace URI?
Definition: fs_uri.c:1279
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:1084
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:219
#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:1460
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:299
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:2145
struct GNUNET_FS_Uri * GNUNET_FS_uri_dup(const struct GNUNET_FS_Uri *uri)
Duplicate URI.
Definition: fs_uri.c:995
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:798
#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:1546
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:1506
static void do_reconnect(void *cls)
Reconnect to the FS service and transmit our queries NOW.
Definition: fs_search.c:1263
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:537
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:103
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint32_t anonymity
Anonymity level for the search.
Definition: fs_api.h:1569
struct GNUNET_HashCode query
Hash of the public key for UBLOCKs; Hash of the CHK-encoded block for DBLOCKS and IBLOCKS...
Definition: fs.h:305
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:360
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:135
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:567
#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:1237
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:1527
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:1968
struct GNUNET_TIME_Relative remaining_probe_time
How much longer should we run the current probe before giving up?
Definition: fs_api.h:569
void * GNUNET_FS_probe_stop(struct GNUNET_FS_SearchResult *sr)
Stop probe activity.
Definition: fs_search.c:542
char * serialization
Random portion of filename we use for syncing state of this download.
Definition: fs_api.h:1794
uint32_t availability_trials
Number of availability trials that we have performed for this search result.
Definition: fs_api.h:598
struct GNUNET_FS_SearchResult * sr
Where to store a pointer to the search result struct if we found a match.
Definition: fs_search.c:158
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:1556
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:1540
#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:484
struct GNUNET_FS_Handle * h
File-sharing context this result belongs to.
Definition: fs_api.h:488
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:243
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:412
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:1264
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:592
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:62
void GNUNET_FS_stop_probe_ping_task_(struct GNUNET_FS_SearchResult *sr)
Stop the ping task for this search result.
Definition: fs_search.c:414
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:1611
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
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:2075
#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:2332
#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:282
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:518
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:1479
static int search_result_free(void *cls, const struct GNUNET_HashCode *key, void *value)
Free the given search result.
Definition: fs_search.c:1741
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:1731
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:602
uint32_t anonymity
Anonymity level to use for probes using this search result.
Definition: fs_api.h:574
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:675
unsigned int keyword_offset
Keyword offset the search result must match (0 for SKS)
Definition: fs_search.c:1037
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:687
Notification that this download is no longer actively being pursued (back in the queue).
Content-hash-key (simple file).
Definition: fs_api.h:140
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:934
struct GNUNET_FS_SearchResult * search
Associated search (used when downloading files based on search results), or NULL for none...
Definition: fs_api.h:1748
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:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:1400
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:1017
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:514
Notification that this download is being resumed.
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:166
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:552
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:1492
#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:152
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:391
Response from FS service with a result for a previous FS search.
Definition: fs.h:346
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:1242
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:355
Signed key space (file in namespace).
Definition: fs_api.h:145
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:57
struct GNUNET_HashCode * xoff
Where to store the keys.
Definition: fs_search.c:1027
#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:581
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:1070
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:493
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:1368
shared definitions for the FS library
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:162
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:1492
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:1127
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:1075
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:1514
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:1686
#define GNUNET_log(kind,...)
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1517
struct GNUNET_FS_Handle * h
Handle to the global FS context.
Definition: fs_api.h:1496
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:1110
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:255
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1736
Location (chk with identity of hosting peer).
Definition: fs_api.h:155
struct GNUNET_TIME_Absolute probe_active_time
When did the current probe become active?
Definition: fs_api.h:564
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:1631
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
#define GNUNET_YES
Definition: gnunet_common.h:77
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:351
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:542
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:1372
#define SEARCH_MESSAGE_OPTION_NONE
No options.
Definition: fs.h:242
#define SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY
Only search the local datastore (no network)
Definition: fs.h:247
Information we keep for each keyword in a keyword search.
Definition: fs_api.h:1454
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:1297
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:1325
struct GNUNET_FS_SearchResult * probes_tail
Tail of active probes.
Definition: fs_api.h:1115
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:1051
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:262
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:1022
void * client_info
Pointer we keep for the client.
Definition: fs_api.h:1522
#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:287
char * keyword
The original keyword, used to derive the key (for decrypting the UBlock).
Definition: fs_api.h:1469
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:1559
struct GNUNET_CRYPTO_EcdsaPublicKey verification_key
Public key used to sign this block.
Definition: block_fs.h:64
#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:1770
void GNUNET_FS_search_start_probe_(struct GNUNET_FS_SearchResult *sr)
Start download probes for the given search result.
Definition: fs_search.c:435
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:743
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:373
#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:949
enum GNUNET_FS_Flags flags
General flags.
Definition: fs_api.h:1148
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:802
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:559
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
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:1060