GNUnet  0.19.4
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 
28 #include "gnunet_fs_service.h"
29 #include "gnunet_protocols.h"
30 #include "fs_api.h"
31 #include "fs_publish_ublock.h"
32 
33 
37 #define AVAILABILITY_TRIALS_MAX 8
38 
48 void *
50  struct GNUNET_FS_Handle *h,
52 {
53  void *ret;
54 
55  pi->value.search.sc = sc;
56  pi->value.search.cctx = (NULL != sc) ? sc->client_info : NULL;
57  pi->value.search.pctx =
58  ((NULL == sc) || (NULL == sc->psearch_result))
59  ? NULL
61  pi->value.search.query = (NULL != sc) ? sc->uri : NULL;
62  pi->value.search.duration = (NULL != sc)
64  sc->start_time)
66  pi->value.search.anonymity = (NULL != sc) ? sc->anonymity : 0;
67  pi->fsh = h;
68  ret = h->upcb (h->upcb_cls, pi);
69  return ret;
70 }
71 
72 
83 static int
85  const struct GNUNET_HashCode *key,
86  void *value)
87 {
88  const struct GNUNET_FS_Uri *uri = cls;
89  struct GNUNET_FS_SearchResult *sr = value;
90 
91  if (GNUNET_FS_uri_test_equal (uri, sr->uri))
92  return GNUNET_SYSERR;
93  return GNUNET_OK;
94 }
95 
96 
104 static void
106  struct GNUNET_FS_SearchResult *sr)
107 {
108  struct GNUNET_FS_ProgressInfo pi;
109 
111  pi.value.search.specifics.result.meta = sr->meta;
112  pi.value.search.specifics.result.uri = sr->uri;
113  pi.value.search.specifics.result.result = sr;
114  pi.value.search.specifics.result.applicability_rank = sr->optional_support;
116 }
117 
118 
126 static void
128  struct GNUNET_FS_SearchResult *sr)
129 {
130  struct GNUNET_FS_ProgressInfo pi;
131 
133  pi.value.search.specifics.update.cctx = sr->client_info;
134  pi.value.search.specifics.update.meta = sr->meta;
135  pi.value.search.specifics.update.uri = sr->uri;
136  pi.value.search.specifics.update.availability_rank =
138  pi.value.search.specifics.update.availability_certainty =
140  pi.value.search.specifics.update.applicability_rank = sr->optional_support;
141  pi.value.search.specifics.update.current_probe_time
144 }
145 
146 
151 {
155  const struct GNUNET_FS_Uri *uri;
156 
162 };
163 
164 
175 static int
177  const struct GNUNET_HashCode *key,
178  void *value)
179 {
180  struct GetResultContext *grc = cls;
181  struct GNUNET_FS_SearchResult *sr = value;
182 
183  if (GNUNET_FS_uri_test_equal (grc->uri, sr->uri))
184  grc->sr = sr;
185  return GNUNET_OK;
186 }
187 
188 
195 static void
197 {
198  struct GNUNET_FS_ProgressInfo pi;
199 
201  pi.value.search.specifics.update.cctx = sr->client_info;
202  pi.value.search.specifics.update.meta = sr->meta;
203  pi.value.search.specifics.update.uri = sr->uri;
204  pi.value.search.specifics.update.availability_rank
206  pi.value.search.specifics.update.availability_certainty
207  = sr->availability_trials;
208  pi.value.search.specifics.update.applicability_rank = sr->optional_support;
209  pi.value.search.specifics.update.current_probe_time
211  sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->h, sr->sc);
213 }
214 
215 
221 static void
223 {
224  struct GNUNET_FS_SearchResult *sr = cls;
225 
226  sr->probe_cancel_task = NULL;
227  sr->availability_trials++;
229  sr->probe_ctx = NULL;
233  "Probe #%u for search result %p failed\n",
235  sr);
236  signal_probe_result (sr);
237 }
238 
239 
245 static void
247 {
248  struct GNUNET_FS_SearchResult *sr = cls;
249 
250  sr->probe_cancel_task = NULL;
251  sr->availability_trials++;
252  sr->availability_success++;
254  sr->probe_ctx = NULL;
258  "Probe #%u for search result %p succeeded\n",
260  sr);
261  signal_probe_result (sr);
262 }
263 
264 
280 void *
282  const struct GNUNET_FS_ProgressInfo *info)
283 {
284  struct GNUNET_FS_SearchResult *sr = info->value.download.cctx;
285  struct GNUNET_TIME_Relative dur;
286 
287  switch (info->status)
288  {
290  /* ignore */
291  break;
293  /* probes should never be resumed */
294  GNUNET_assert (0);
295  break;
297  /* probes should never be suspended */
298  GNUNET_break (0);
299  break;
301  /* ignore */
302  break;
304  if (NULL != sr->probe_cancel_task)
305  {
307  sr->probe_cancel_task = NULL;
308  }
309  sr->probe_cancel_task =
311  &probe_failure_handler, sr);
312  break;
314  if (NULL != sr->probe_cancel_task)
315  {
317  sr->probe_cancel_task = NULL;
318  }
319  sr->probe_cancel_task =
321  break;
323  if (NULL != sr->probe_cancel_task)
324  {
326  sr->probe_cancel_task = NULL;
327  }
328  sr = NULL;
329  break;
331  if (NULL == sr->probe_cancel_task)
332  {
334  sr->probe_cancel_task =
336  &probe_failure_handler, sr);
337  }
338  break;
340  if (NULL != sr->probe_cancel_task)
341  {
343  sr->probe_cancel_task = NULL;
344  }
348  if (0 == sr->remaining_probe_time.rel_value_us)
349  sr->probe_cancel_task =
352  break;
353 
354  default:
355  GNUNET_break (0);
356  return NULL;
357  }
358  return sr;
359 }
360 
361 
367 static void
369 {
370  struct GNUNET_FS_Handle *h = cls;
371 
372  for (struct GNUNET_FS_SearchResult *sr = h->probes_head;
373  NULL != sr;
374  sr = sr->next)
375  if (NULL != sr->probe_ctx->mq)
376  signal_probe_result (sr);
377  h->probe_ping_task
380  h);
381 }
382 
383 
389 static void
391 {
392  struct GNUNET_FS_Handle *h = sr->h;
393 
394  GNUNET_CONTAINER_DLL_insert (h->probes_head,
395  h->probes_tail,
396  sr);
397  if (NULL == h->probe_ping_task)
398  h->probe_ping_task
400  h);
401 }
402 
403 
409 void
411 {
412  struct GNUNET_FS_Handle *h = sr->h;
413 
414  GNUNET_CONTAINER_DLL_remove (h->probes_head,
415  h->probes_tail,
416  sr);
417  if (NULL == h->probes_head)
418  {
419  GNUNET_SCHEDULER_cancel (h->probe_ping_task);
420  h->probe_ping_task = NULL;
421  }
422 }
423 
424 
430 void
432 {
433  uint64_t off;
434  uint64_t len;
435 
436  if (NULL != sr->probe_ctx)
437  return;
438  if (NULL != sr->download)
439  return;
440  if (0 == (sr->h->flags & GNUNET_FS_FLAGS_DO_PROBES))
441  return;
443  return;
444  if ( (GNUNET_FS_URI_CHK != sr->uri->type) &&
445  (GNUNET_FS_URI_LOC != sr->uri->type) )
446  return;
448  if (0 == len)
449  return;
450  if ((len <= DBLOCK_SIZE) && (sr->availability_success > 0))
451  return;
452  off = len / DBLOCK_SIZE;
453  if (off > 0)
455  off *= DBLOCK_SIZE;
456  if (len - off < DBLOCK_SIZE)
457  len = len - off;
458  else
459  len = DBLOCK_SIZE;
461  "Starting probe #%u (at offset %llu) for search result %p\n",
462  sr->availability_trials + 1,
463  (unsigned long long) off,
464  sr);
467  2 * (1
468  + sr->availability_trials));
469  sr->probe_ctx =
470  GNUNET_FS_download_start (sr->h, sr->uri, sr->meta, NULL, NULL, off,
471  len, sr->anonymity,
473  | GNUNET_FS_DOWNLOAD_IS_PROBE, sr, NULL);
475 }
476 
477 
488 struct GNUNET_FS_SearchResult *
490  const struct GNUNET_FS_Uri *uri,
491  const struct GNUNET_FS_MetaData *meta,
492  void *client_info,
493  uint32_t anonymity)
494 {
495  struct GNUNET_FS_SearchResult *sr;
496 
497  GNUNET_assert (NULL != h);
498  GNUNET_assert (NULL != uri);
499  sr = GNUNET_new (struct GNUNET_FS_SearchResult);
500  sr->h = h;
501  sr->uri = GNUNET_FS_uri_dup (uri);
503  sr->client_info = client_info;
504  sr->anonymity = anonymity;
506  return sr;
507 }
508 
509 
515 static void
517 {
518  if (NULL != sr->probe_ctx)
519  {
521  sr->probe_ctx = NULL;
523  }
524  if (NULL != sr->probe_cancel_task)
525  {
527  sr->probe_cancel_task = NULL;
528  }
529 }
530 
531 
539 void *
541 {
542  void *client_info;
543 
544  GNUNET_assert (NULL == sr->sc);
548  client_info = sr->client_info;
549  GNUNET_free (sr);
550  return client_info;
551 }
552 
553 
564 static void
566  struct SearchRequestEntry *ent,
567  const struct GNUNET_FS_Uri *uri,
568  const struct GNUNET_FS_MetaData *meta)
569 {
570  struct GNUNET_HashCode key;
571  struct GNUNET_FS_SearchResult *sr;
572  struct GetResultContext grc;
573  int is_new;
574  unsigned int koff;
575 
576  /* check if new */
577  GNUNET_assert (NULL != sc);
578  if (GNUNET_OK !=
580  &key))
581  {
582  GNUNET_break_op (0);
583  return;
584  }
585  if (GNUNET_SYSERR ==
587  &key,
589  (void *) uri))
590  return; /* duplicate result */
591  /* try to find search result in master map */
592  grc.sr = NULL;
593  grc.uri = uri;
595  &key,
596  &get_result_present, &grc);
597  sr = grc.sr;
598  is_new = (NULL == sr) || (sr->mandatory_missing > 0);
599  if (NULL == sr)
600  {
602  sr->h = sc->h;
603  sr->sc = sc;
604  sr->anonymity = sc->anonymity;
608  sr->key = key;
609  sr->keyword_bitmap = GNUNET_malloc ((sc->uri->data.ksk.keywordCount + 7)
610  / 8); /* round up, count bits */
613  }
614  else
615  {
617  }
620  &sr->key,
621  sr,
623 
624  koff = ent - sc->requests;
625  GNUNET_assert ((ent >= sc->requests) &&
626  (koff < sc->uri->data.ksk.keywordCount));
627  sr->keyword_bitmap[koff / 8] |= (1 << (koff % 8));
628  /* check if mandatory satisfied */
630  {
631  if (ent->mandatory)
632  {
635  }
636  else
637  {
638  sr->optional_support++;
639  }
640  }
641  if (0 != sr->mandatory_missing)
642  {
643  GNUNET_break (NULL == sr->client_info);
644  return;
645  }
646  if (is_new)
648  else
652 }
653 
654 
667 static struct GNUNET_FS_SearchContext *
669  const struct GNUNET_FS_Uri *uri,
670  uint32_t anonymity,
672  void *cctx,
673  struct GNUNET_FS_SearchResult *psearch);
674 
675 
685 static void
687  const char *id_update,
688  const struct GNUNET_FS_Uri *uri,
689  const struct GNUNET_FS_MetaData *meta)
690 {
691  struct GNUNET_FS_Uri uu;
692  struct GNUNET_HashCode key;
693  struct GNUNET_FS_SearchResult *sr;
694 
695  /* check if new */
696  GNUNET_assert (NULL != sc);
697  if (GNUNET_OK !=
699  &key))
700  {
701  GNUNET_break (0);
702  return;
703  }
705  &uri->data.chk.chk.query,
706  &key);
707  if (GNUNET_SYSERR ==
710  (void *) uri))
711  return; /* duplicate result */
712  sr = GNUNET_new (struct GNUNET_FS_SearchResult);
713  sr->h = sc->h;
714  sr->sc = sc;
715  sr->anonymity = sc->anonymity;
716  sr->uri = GNUNET_FS_uri_dup (uri);
718  sr->key = key;
723  /* notify client */
724  if (0 == sr->mandatory_missing)
726  else
727  GNUNET_break (NULL == sr->client_info);
728  /* search for updates */
729  if (0 == strlen (id_update))
730  return; /* no updates */
731  uu.type = GNUNET_FS_URI_SKS;
732  uu.data.sks.ns = sc->uri->data.sks.ns;
733  uu.data.sks.identifier = GNUNET_strdup (id_update);
734  (void) search_start (sc->h, &uu, sc->anonymity, sc->options, NULL, sr);
735  GNUNET_free (uu.data.sks.identifier);
736 }
737 
738 
753 static int
755  const struct GNUNET_CRYPTO_EcdsaPublicKey *dpub,
756  const void *edata,
757  size_t edata_size,
758  char *data)
759 {
760  const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon;
761  struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
762  unsigned int i;
763 
764  /* find key */
765  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
766  if (0 == memcmp (dpub,
767  &sc->requests[i].dpub,
768  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
769  break;
770  if (i == sc->uri->data.ksk.keywordCount)
771  {
772  /* oops, does not match any of our keywords!? */
773  GNUNET_break (0);
774  return GNUNET_SYSERR;
775  }
776  /* decrypt */
778  GNUNET_CRYPTO_ecdsa_key_get_public (anon, &anon_pub);
779  GNUNET_FS_ublock_decrypt_ (edata, edata_size,
780  &anon_pub,
781  sc->requests[i].keyword,
782  data);
783  return i;
784 }
785 
786 
796 static void
798  const struct UBlock *ub,
799  size_t size)
800 {
801  size_t j;
802  char pt[size - sizeof(struct UBlock)];
803  const char *eos;
804  struct GNUNET_FS_MetaData *meta;
805  struct GNUNET_FS_Uri *uri;
806  char *emsg;
807  int i;
808 
809  if (-1 == (i = decrypt_block_with_keyword (sc,
810  &ub->verification_key,
811  &ub[1],
812  size - sizeof(struct UBlock),
813  pt)))
814  return;
815  /* parse; pt[0] is just '\0', so we skip over that */
816  eos = memchr (&pt[1], '\0', sizeof(pt) - 1);
817  if (NULL == eos)
818  {
819  GNUNET_break_op (0);
820  return;
821  }
822  if (NULL == (uri = GNUNET_FS_uri_parse (&pt[1], &emsg)))
823  {
824  if (GNUNET_FS_VERSION > 0x00090400)
825  {
826  /* we broke this in 0x00090300, so don't bitch
827  too loudly just one version up... */
828  GNUNET_break_op (0); /* ublock malformed */
830  _ ("Failed to parse URI `%s': %s\n"),
831  &pt[1],
832  emsg);
833  }
834  GNUNET_free (emsg);
835  return;
836  }
837  j = eos - pt + 1;
838  if (sizeof(pt) == j)
840  else
841  meta = GNUNET_FS_meta_data_deserialize (&pt[j], sizeof(pt) - j);
842  if (NULL == meta)
843  {
844  GNUNET_break_op (0); /* ublock malformed */
846  return;
847  }
849  &sc->requests[i],
850  uri,
851  meta);
852 
853  /* clean up */
856 }
857 
858 
868 static void
870  const struct UBlock *ub,
871  size_t size)
872 {
873  size_t len = size - sizeof(struct UBlock);
874  char pt[len];
875  struct GNUNET_FS_Uri *uri;
876  struct GNUNET_FS_MetaData *meta;
877  const char *id;
878  const char *uris;
879  size_t off;
880  char *emsg;
881 
883  &sc->uri->data.sks.ns,
884  sc->uri->data.sks.identifier,
885  pt);
886  /* parse */
887  if (0 == (off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris)))
888  {
889  GNUNET_break_op (0); /* ublock malformed */
890  return;
891  }
892  if (NULL == (meta = GNUNET_FS_meta_data_deserialize (&pt[off], len
893  - 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 (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  cm->expiration)).rel_value_us > 0)
958  {
960  "Result received has already expired.\n");
961  return; /* result expired */
962  }
963  switch (type)
964  {
966  if (GNUNET_FS_URI_SKS == sc->uri->type)
968  (const struct UBlock *) &cm[1],
969  msize);
970  else
972  (const struct UBlock *) &cm[1],
973  msize);
974  break;
975 
977  GNUNET_break (0);
978  break;
979 
981  GNUNET_break (0);
982  break;
983 
985  GNUNET_break (0);
986  break;
987 
989  GNUNET_break (0);
990  break;
991 
992  default:
994  _ ("Got result with unknown block type `%d', ignoring"),
995  type);
996  break;
997  }
998 }
999 
1000 
1007 static void
1009 
1010 
1015 {
1019  unsigned int put_cnt;
1020 
1024  unsigned int skip_cnt;
1025 
1030 
1035 
1039  unsigned int keyword_offset;
1040 };
1041 
1042 
1052 static int
1053 build_result_set (void *cls,
1054  const struct GNUNET_HashCode *key,
1055  void *value)
1056 {
1057  struct MessageBuilderContext *mbc = cls;
1058  struct GNUNET_FS_SearchResult *sr = value;
1059 
1060  if ((NULL != sr->keyword_bitmap) &&
1061  (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1
1062  << (mbc->
1063  keyword_offset
1064  % 8)))))
1065  return GNUNET_OK; /* have no match for this keyword yet */
1066  if (mbc->skip_cnt > 0)
1067  {
1068  mbc->skip_cnt--;
1069  return GNUNET_OK;
1070  }
1071  if (0 == mbc->put_cnt)
1072  return GNUNET_SYSERR;
1073  mbc->xoff[--mbc->put_cnt] = *key;
1074 
1075  return GNUNET_OK;
1076 }
1077 
1078 
1088 static int
1089 find_result_set (void *cls,
1090  const struct GNUNET_HashCode *key,
1091  void *value)
1092 {
1093  struct MessageBuilderContext *mbc = cls;
1094  struct GNUNET_FS_SearchResult *sr = value;
1095 
1096  if ((NULL != sr->keyword_bitmap) &&
1097  (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1
1098  << (mbc->
1099  keyword_offset
1100  % 8)))))
1101  return GNUNET_OK; /* have no match for this keyword yet */
1102  mbc->put_cnt++;
1103  return GNUNET_OK;
1104 }
1105 
1106 
1113 static void
1115 {
1116  struct MessageBuilderContext mbc;
1117  struct GNUNET_MQ_Envelope *env;
1118  struct SearchMessage *sm;
1119  struct GNUNET_CRYPTO_EcdsaPublicKey dpub;
1120  unsigned int total_seen_results; /* total number of result hashes to send */
1121  uint32_t options;
1122  unsigned int left;
1123  unsigned int todo;
1124  unsigned int fit;
1125  unsigned int search_request_map_offset;
1126  unsigned int keyword_offset;
1127  int first_call;
1128 
1129  memset (&mbc, 0, sizeof(mbc));
1130  mbc.sc = sc;
1131  if (GNUNET_FS_uri_test_ksk (sc->uri))
1132  {
1133  /* This will calculate the result set size ONLY for
1134  "keyword_offset == 0", so we will have to recalculate
1135  it for the other keywords later! */
1137  &find_result_set,
1138  &mbc);
1139  total_seen_results = mbc.put_cnt;
1140  }
1141  else
1142  {
1143  total_seen_results
1145  }
1146  search_request_map_offset = 0;
1147  keyword_offset = 0;
1148  first_call = GNUNET_YES;
1149  while ((0 != (left =
1150  (total_seen_results - search_request_map_offset))) ||
1151  (GNUNET_YES == first_call))
1152  {
1153  first_call = GNUNET_NO;
1157 
1158  fit = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof(*sm)) / sizeof(struct
1159  GNUNET_HashCode);
1160  todo = GNUNET_MIN (fit,
1161  left);
1162  env = GNUNET_MQ_msg_extra (sm,
1163  sizeof(struct GNUNET_HashCode) * todo,
1165  mbc.skip_cnt = search_request_map_offset;
1166  mbc.xoff = (struct GNUNET_HashCode *) &sm[1];
1167  sm->type = htonl (GNUNET_BLOCK_TYPE_FS_UBLOCK);
1168  sm->anonymity_level = htonl (sc->anonymity);
1169  memset (&sm->target,
1170  0,
1171  sizeof(struct GNUNET_PeerIdentity));
1172 
1173  if (GNUNET_FS_uri_test_ksk (sc->uri))
1174  {
1175  mbc.keyword_offset = keyword_offset;
1176  /* calculate how many results we can send in this message */
1177  mbc.put_cnt = todo;
1178  /* now build message */
1179  sm->query = sc->requests[keyword_offset].uquery;
1182  &mbc);
1183  search_request_map_offset += todo;
1184  GNUNET_assert (0 == mbc.put_cnt);
1185  GNUNET_assert (total_seen_results >= search_request_map_offset);
1186  if (total_seen_results != search_request_map_offset)
1187  {
1188  /* more requesting to be done... */
1190  }
1191  else
1192  {
1193  sm->options = htonl (options);
1194  keyword_offset++;
1195  if (sc->uri->data.ksk.keywordCount != keyword_offset)
1196  {
1197  /* more keywords => more requesting to be done... */
1198  first_call = GNUNET_YES;
1199  search_request_map_offset = 0;
1200  mbc.put_cnt = 0;
1201  mbc.keyword_offset = keyword_offset;
1203  &find_result_set,
1204  &mbc);
1205  total_seen_results = mbc.put_cnt;
1206  }
1207  }
1208  }
1209  else
1210  {
1212 
1214  sc->uri->data.sks.identifier,
1215  "fs-ublock",
1216  &dpub);
1217  GNUNET_CRYPTO_hash (&dpub,
1218  sizeof(dpub),
1219  &sm->query);
1220  mbc.put_cnt = todo;
1221  mbc.keyword_offset = 0;
1224  &mbc);
1225  GNUNET_assert (total_seen_results >= search_request_map_offset);
1226  if (total_seen_results != search_request_map_offset)
1227  {
1228  /* more requesting to be done... */
1230  }
1231  else
1232  {
1233  sm->options = htonl (options);
1234  }
1235  }
1236  GNUNET_MQ_send (sc->mq,
1237  env);
1238  }
1239 }
1240 
1241 
1250 static void
1252  enum GNUNET_MQ_Error error)
1253 {
1254  struct GNUNET_FS_SearchContext *sc = cls;
1255 
1256  if (NULL != sc->mq)
1257  {
1258  GNUNET_MQ_destroy (sc->mq);
1259  sc->mq = NULL;
1260  }
1261  try_reconnect (sc);
1262 }
1263 
1264 
1271 static void
1272 do_reconnect (void *cls)
1273 {
1274  struct GNUNET_FS_SearchContext *sc = cls;
1275  struct GNUNET_MQ_MessageHandler handlers[] = {
1278  struct ClientPutMessage,
1279  sc),
1281  };
1282 
1283  sc->task = NULL;
1285  "fs",
1286  handlers,
1288  sc);
1289  if (NULL == sc->mq)
1290  {
1291  try_reconnect (sc);
1292  return;
1293  }
1295 }
1296 
1297 
1305 static void
1307 {
1308  if (NULL != sc->mq)
1309  {
1310  GNUNET_MQ_destroy (sc->mq);
1311  sc->mq = NULL;
1312  }
1314  sc->task =
1316  &do_reconnect,
1317  sc);
1318 }
1319 
1320 
1333 static struct GNUNET_FS_SearchContext *
1335  const struct GNUNET_FS_Uri *uri,
1336  uint32_t anonymity,
1338  void *cctx,
1339  struct GNUNET_FS_SearchResult *psearch)
1340 {
1341  struct GNUNET_FS_SearchContext *sc;
1342  struct GNUNET_FS_ProgressInfo pi;
1343 
1345  sc->h = h;
1346  sc->options = options;
1347  sc->uri = GNUNET_FS_uri_dup (uri);
1348  sc->anonymity = anonymity;
1350  if (NULL != psearch)
1351  {
1352  sc->psearch_result = psearch;
1353  psearch->update_search = sc;
1354  }
1356  sc->client_info = cctx;
1358  {
1361  GNUNET_free (sc);
1362  return NULL;
1363  }
1367  return sc;
1368 }
1369 
1370 
1380 static int
1382  const struct GNUNET_HashCode *key,
1383  void *value)
1384 {
1385  struct GNUNET_FS_SearchContext *sc = cls;
1386  struct GNUNET_FS_SearchResult *sr = value;
1387 
1388  for (unsigned int i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1389  {
1390  if (0 != (sr->keyword_bitmap[i / 8] & (1 << (i % 8))))
1393  &sr->key,
1394  sr,
1396  }
1397  return GNUNET_YES;
1398 }
1399 
1400 
1401 int
1403 {
1404  unsigned int i;
1405  const char *keyword;
1406  const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon;
1407  struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
1408  struct SearchRequestEntry *sre;
1409 
1410  GNUNET_assert (NULL == sc->mq);
1411  if (GNUNET_FS_uri_test_ksk (sc->uri))
1412  {
1413  GNUNET_assert (0 != sc->uri->data.ksk.keywordCount);
1415  GNUNET_CRYPTO_ecdsa_key_get_public (anon, &anon_pub);
1416  sc->requests
1417  = GNUNET_new_array (sc->uri->data.ksk.keywordCount,
1418  struct SearchRequestEntry);
1419 
1420  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1421  {
1422  keyword = &sc->uri->data.ksk.keywords[i][1];
1423  sre = &sc->requests[i];
1424  sre->keyword = GNUNET_strdup (keyword);
1426  keyword,
1427  "fs-ublock",
1428  &sre->dpub);
1429  GNUNET_CRYPTO_hash (&sre->dpub,
1430  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
1431  &sre->uquery);
1432  sre->mandatory = (sc->uri->data.ksk.keywords[i][0] == '+');
1433  if (sre->mandatory)
1434  sc->mandatory_count++;
1436  }
1439  sc);
1440  }
1441  GNUNET_assert (NULL == sc->task);
1442  do_reconnect (sc);
1443  if (NULL == sc->mq)
1444  {
1446  sc->task = NULL;
1447  return GNUNET_SYSERR;
1448  }
1449  return GNUNET_OK;
1450 }
1451 
1452 
1461 static int
1463  const struct GNUNET_HashCode *key,
1464  void *value)
1465 {
1466  struct GNUNET_FS_SearchResult *sr = value;
1467 
1468  if (NULL != sr->probe_ctx)
1469  {
1471  sr->probe_ctx = NULL;
1473  }
1474  if (NULL != sr->probe_cancel_task)
1475  {
1477  sr->probe_cancel_task = NULL;
1478  }
1479  if (NULL != sr->update_search)
1481  return GNUNET_OK;
1482 }
1483 
1484 
1493 static int
1495  const struct GNUNET_HashCode *key,
1496  void *value)
1497 {
1498  struct GNUNET_FS_SearchResult *sr = value;
1499 
1501  if (NULL != sr->update_search)
1503  return GNUNET_OK;
1504 }
1505 
1506 
1515 static int
1517  const struct GNUNET_HashCode *key,
1518  void *value)
1519 {
1520  struct GNUNET_FS_SearchContext *sc = cls;
1521  struct GNUNET_FS_SearchResult *sr = value;
1522  struct GNUNET_FS_ProgressInfo pi;
1523 
1524  if (NULL != sr->download)
1525  {
1527  sr->download = NULL;
1528  }
1529  if (NULL != sr->update_search)
1530  {
1532  sr->update_search = NULL;
1533  }
1535  if (0 == sr->mandatory_missing)
1536  {
1537  /* client is aware of search result, notify about suspension event */
1539  pi.value.search.specifics.result_suspend.cctx = sr->client_info;
1540  pi.value.search.specifics.result_suspend.meta = sr->meta;
1541  pi.value.search.specifics.result_suspend.uri = sr->uri;
1543  }
1544  GNUNET_break (NULL == sr->client_info);
1545  GNUNET_free (sr->serialization);
1546  GNUNET_FS_uri_destroy (sr->uri);
1549  GNUNET_free (sr);
1550  return GNUNET_OK;
1551 }
1552 
1553 
1554 void
1556 {
1557  struct GNUNET_FS_SearchContext *sc = cls;
1558  struct GNUNET_FS_ProgressInfo pi;
1559  unsigned int i;
1560 
1561  GNUNET_FS_end_top (sc->h, sc->top);
1566  GNUNET_break (NULL == sc->client_info);
1567  if (sc->task != NULL)
1568  {
1570  sc->task = NULL;
1571  }
1572  if (NULL != sc->mq)
1573  {
1574  GNUNET_MQ_destroy (sc->mq);
1575  sc->mq = NULL;
1576  }
1578  if (NULL != sc->requests)
1579  {
1581  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1582  {
1585  }
1586  }
1587  GNUNET_free (sc->requests);
1588  GNUNET_free (sc->emsg);
1591  GNUNET_free (sc);
1592 }
1593 
1594 
1606 struct GNUNET_FS_SearchContext *
1608  const struct GNUNET_FS_Uri *uri, uint32_t anonymity,
1609  enum GNUNET_FS_SearchOptions options, void *cctx)
1610 {
1611  struct GNUNET_FS_SearchContext *ret;
1612 
1613  ret = search_start (h, uri, anonymity, options, cctx, NULL);
1614  if (NULL == ret)
1615  return NULL;
1617  return ret;
1618 }
1619 
1620 
1626 void
1628 {
1629  struct GNUNET_FS_ProgressInfo pi;
1630 
1631  if (NULL != sc->task)
1632  {
1634  sc->task = NULL;
1635  }
1636  if (NULL != sc->mq)
1637  {
1638  GNUNET_MQ_destroy (sc->mq);
1639  sc->mq = NULL;
1640  }
1644  sc);
1647  sc->h,
1648  sc);
1649 }
1650 
1651 
1657 void
1659 {
1660  struct GNUNET_FS_ProgressInfo pi;
1661 
1662  GNUNET_assert (NULL == sc->mq);
1663  GNUNET_assert (NULL == sc->task);
1664  do_reconnect (sc);
1670 }
1671 
1672 
1681 static int
1683  const struct GNUNET_HashCode *key,
1684  void *value)
1685 {
1686  struct GNUNET_FS_SearchContext *sc = cls;
1687  struct GNUNET_FS_SearchResult *sr = value;
1688  struct GNUNET_FS_ProgressInfo pi;
1689 
1691  if (NULL != sr->download)
1692  {
1693  sr->download->search = NULL;
1694  sr->download->top
1695  = GNUNET_FS_make_top (sr->download->h,
1697  sr->download);
1698  if (NULL != sr->download->serialization)
1699  {
1702  sr->download->serialization);
1704  sr->download->serialization = NULL;
1705  }
1708  sr->download);
1710  sr->download = NULL;
1711  }
1712  if (0 != sr->mandatory_missing)
1713  {
1714  /* client is unaware of search result as
1715  it does not match required keywords */
1716  GNUNET_break (NULL == sr->client_info);
1717  return GNUNET_OK;
1718  }
1720  pi.value.search.specifics.result_stopped.cctx = sr->client_info;
1721  pi.value.search.specifics.result_stopped.meta = sr->meta;
1722  pi.value.search.specifics.result_stopped.uri = sr->uri;
1724  return GNUNET_OK;
1725 }
1726 
1727 
1736 static int
1738  const struct GNUNET_HashCode *key,
1739  void *value)
1740 {
1741  struct GNUNET_FS_SearchResult *sr = value;
1742 
1743  if (NULL != sr->update_search)
1744  {
1746  GNUNET_assert (NULL == sr->update_search);
1747  }
1748  GNUNET_break (NULL == sr->probe_ctx);
1749  GNUNET_break (NULL == sr->probe_cancel_task);
1750  GNUNET_break (NULL == sr->client_info);
1751  GNUNET_free (sr->serialization);
1752  GNUNET_FS_uri_destroy (sr->uri);
1755  GNUNET_free (sr);
1756  return GNUNET_OK;
1757 }
1758 
1759 
1765 void
1767 {
1768  struct GNUNET_FS_ProgressInfo pi;
1769  unsigned int i;
1770 
1771  if (NULL != sc->top)
1772  GNUNET_FS_end_top (sc->h, sc->top);
1775  sc);
1776  if (NULL != sc->psearch_result)
1777  sc->psearch_result->update_search = NULL;
1778  if (NULL != sc->serialization)
1779  {
1781  (NULL != sc->psearch_result)
1784  sc->serialization);
1786  (NULL != sc->psearch_result)
1789  sc->serialization);
1791  }
1794  sc->h,
1795  sc);
1796  GNUNET_break (NULL == sc->client_info);
1797  if (NULL != sc->task)
1798  {
1800  sc->task = NULL;
1801  }
1802  if (NULL != sc->mq)
1803  {
1804  GNUNET_MQ_destroy (sc->mq);
1805  sc->mq = NULL;
1806  }
1810  if (NULL != sc->requests)
1811  {
1813  for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1814  {
1817  }
1818  }
1819  GNUNET_free (sc->requests);
1820  GNUNET_free (sc->emsg);
1822  GNUNET_free (sc);
1823 }
1824 
1825 
1826 /* end of fs_search.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_FS_UBLOCK
Type of a block representing any type of search result (universal).
@ GNUNET_BLOCK_TYPE_FS_IBLOCK
Inner block in the CHK tree.
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
@ GNUNET_BLOCK_TYPE_FS_ONDEMAND
Type of a block representing a block to be encoded on demand from disk.
@ GNUNET_BLOCK_TYPE_FS_DBLOCK
Data block (leaf) in the CHK tree.
#define SEARCH_MESSAGE_OPTION_NONE
No options.
Definition: fs.h:249
#define SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY
Only search the local datastore (no network)
Definition: fs.h:254
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:41
#define SEARCH_MESSAGE_OPTION_CONTINUED
Request is too large to fit in 64k format.
Definition: fs.h:262
void GNUNET_FS_search_result_sync_(struct GNUNET_FS_SearchResult *sr)
Synchronize this search result with its mirror on disk.
Definition: fs_api.c:2149
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:381
void GNUNET_FS_search_sync_(struct GNUNET_FS_SearchContext *sc)
Synchronize this search struct with its mirror on disk.
Definition: fs_api.c:2248
void GNUNET_FS_download_sync_(struct GNUNET_FS_DownloadContext *dc)
Synchronize this download struct with its mirror on disk.
Definition: fs_api.c:2036
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:728
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:787
void GNUNET_FS_end_top(struct GNUNET_FS_Handle *h, struct TopLevelActivity *top)
Destroy a top-level activity entry.
Definition: fs_api.c:402
shared definitions for the FS library
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
@ GNUNET_FS_URI_LOC
Location (chk with identity of hosting peer).
Definition: fs_api.h:159
@ GNUNET_FS_URI_CHK
Content-hash-key (simple file).
Definition: fs_api.h:144
@ GNUNET_FS_URI_SKS
Signed key space (file in namespace).
Definition: fs_api.h:149
#define GNUNET_FS_SYNC_PATH_MASTER_SEARCH
Name of the directory with top-level searches.
Definition: fs_api.h:55
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:104
#define GNUNET_FS_SYNC_PATH_CHILD_SEARCH
Name of the directory with sub-searches (namespace-updates).
Definition: fs_api.h:60
#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:72
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.
publish a UBLOCK in GNUnet
static void notify_client_chk_update(struct GNUNET_FS_SearchContext *sc, struct GNUNET_FS_SearchResult *sr)
We've found new information about an existing CHK result.
Definition: fs_search.c:127
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:1682
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:1114
static int update_sre_result_maps(void *cls, const struct GNUNET_HashCode *key, void *value)
Update the 'results' map for the individual keywords with the results from the 'global' result set.
Definition: fs_search.c:1381
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:49
#define AVAILABILITY_TRIALS_MAX
Number of availability trials we perform per search result.
Definition: fs_search.c:37
void GNUNET_FS_stop_probe_ping_task_(struct GNUNET_FS_SearchResult *sr)
Stop the ping task for this search result.
Definition: fs_search.c:410
static void probe_success_handler(void *cls)
Handle the case where we have gotten a response for our probe.
Definition: fs_search.c:246
static void start_probe_ping_task(struct GNUNET_FS_SearchResult *sr)
Start the ping task for this search result.
Definition: fs_search.c:390
static void probe_ping_task_cb(void *cls)
Task run periodically to remind clients that a probe is active.
Definition: fs_search.c:368
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:1334
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:797
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:176
void GNUNET_FS_search_start_probe_(struct GNUNET_FS_SearchResult *sr)
Start download probes for the given search result.
Definition: fs_search.c:431
static int check_result(void *cls, const struct ClientPutMessage *cm)
We check a result message from the service.
Definition: fs_search.c:934
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:196
static void process_sks_result(struct GNUNET_FS_SearchContext *sc, const char *id_update, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_MetaData *meta)
We have received an SKS result.
Definition: fs_search.c:686
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:1494
static void do_reconnect(void *cls)
Reconnect to the FS service and transmit our queries NOW.
Definition: fs_search.c:1272
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:281
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:1516
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:1053
static int search_result_free(void *cls, const struct GNUNET_HashCode *key, void *value)
Free the given search result.
Definition: fs_search.c:1737
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:1402
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 'keyword' as the passphrase.
Definition: fs_search.c:754
static void handle_result(void *cls, const struct ClientPutMessage *cm)
We process a search result from the service.
Definition: fs_search.c:949
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:222
static void GNUNET_FS_search_stop_probe_(struct GNUNET_FS_SearchResult *sr)
Stop probing activity associated with a search result.
Definition: fs_search.c:516
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:84
static void notify_client_chk_result(struct GNUNET_FS_SearchContext *sc, struct GNUNET_FS_SearchResult *sr)
We've found a new CHK result.
Definition: fs_search.c:105
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:1306
static void process_ksk_result(struct GNUNET_FS_SearchContext *sc, struct SearchRequestEntry *ent, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_MetaData *meta)
We have received a KSK result.
Definition: fs_search.c:565
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:1089
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:1251
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:869
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:1462
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:1555
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int anonymity
uint32_t data
The data value.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * value
Value of the record to add/remove.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static struct GNUNET_FS_MetaData * meta
Meta-data provided via command-line option.
static int result
Global testing status.
#define info
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:87
API for file sharing via GNUnet.
Constants for network protocols.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
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:1057
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.
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:481
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
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:186
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_FS_SearchResult * GNUNET_FS_probe(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_MetaData *meta, void *client_info, uint32_t anonymity)
Start download probes for the given search result.
Definition: fs_search.c:489
GNUNET_FS_SearchOptions
Options for searching.
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:637
#define GNUNET_FS_PROBE_UPDATE_FREQUENCY
How often do we signal applications that a probe for a particular search result is running?...
#define GNUNET_FS_VERSION
Version number of the implementation.
void GNUNET_FS_search_continue(struct GNUNET_FS_SearchContext *sc)
Continue paused search.
Definition: fs_search.c:1658
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:1360
int GNUNET_FS_uri_test_ksk(const struct GNUNET_FS_Uri *uri)
Is this a keyword URI?
Definition: fs_uri.c:1324
void * GNUNET_FS_probe_stop(struct GNUNET_FS_SearchResult *sr)
Stop probe activity.
Definition: fs_search.c:540
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:1201
void GNUNET_FS_search_stop(struct GNUNET_FS_SearchContext *sc)
Stop search for content.
Definition: fs_search.c:1766
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:677
struct GNUNET_FS_DownloadContext * GNUNET_FS_download_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_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:2100
int GNUNET_FS_uri_test_sks(const struct GNUNET_FS_Uri *uri)
Is this a namespace URI?
Definition: fs_uri.c:1271
struct GNUNET_FS_Uri * GNUNET_FS_uri_dup(const struct GNUNET_FS_Uri *uri)
Duplicate URI.
Definition: fs_uri.c:987
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:2254
void GNUNET_FS_search_pause(struct GNUNET_FS_SearchContext *sc)
Pause search.
Definition: fs_search.c:1627
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:96
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:1607
@ GNUNET_FS_FLAGS_DO_PROBES
Should we automatically trigger probes for search results to determine availability?...
@ GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY
Only search the local host, do not search remote systems (no P2P)
@ GNUNET_FS_DOWNLOAD_IS_PROBE
Internal option used to flag this download as a 'probe' for a search result.
@ GNUNET_FS_DOWNLOAD_NO_TEMPORARIES
Do not append temporary data to the target file (for the IBlocks).
@ GNUNET_FS_STATUS_SEARCH_UPDATE
We have additional data about the quality or availability of a search result.
@ GNUNET_FS_STATUS_DOWNLOAD_INACTIVE
Notification that this download is no longer actively being pursued (back in the queue).
@ GNUNET_FS_STATUS_DOWNLOAD_ERROR
Notification that this download encountered an error.
@ GNUNET_FS_STATUS_DOWNLOAD_COMPLETED
Notification that this download completed.
@ GNUNET_FS_STATUS_DOWNLOAD_RESUME
Notification that this download is being resumed.
@ GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED
Event generated for each search result when the respective search is stopped.
@ GNUNET_FS_STATUS_SEARCH_SUSPEND
Last event when a search is being suspended; note that "GNUNET_FS_SEARCH_STOPPED" will not be generat...
@ GNUNET_FS_STATUS_DOWNLOAD_SUSPEND
Notification that this download was suspended.
@ GNUNET_FS_STATUS_SEARCH_RESULT
This search has yielded a result.
@ GNUNET_FS_STATUS_SEARCH_CONTINUED
Signals that this search was continued (unpaused).
@ GNUNET_FS_STATUS_DOWNLOAD_START
Notification that we have started this download.
@ GNUNET_FS_STATUS_SEARCH_PAUSED
Signals that this search was paused.
@ GNUNET_FS_STATUS_DOWNLOAD_PROGRESS
Notification about progress with this download.
@ GNUNET_FS_STATUS_DOWNLOAD_LOST_PARENT
Notification that this download is no longer part of a recursive download or search but now a 'stand-...
@ GNUNET_FS_STATUS_SEARCH_START
First event generated when a client requests a search to begin or when a namespace result automatical...
@ GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND
Event generated for each search result when the respective search is suspended.
@ GNUNET_FS_STATUS_DOWNLOAD_ACTIVE
Notification that this download is now actively being pursued (as opposed to waiting in the queue).
@ GNUNET_FS_STATUS_DOWNLOAD_STOPPED
Notification that this download was stopped (final event with respect to this action).
@ GNUNET_FS_STATUS_SEARCH_STOPPED
Last message from a search; this signals that there will be no further events associated with this se...
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
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:135
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
enum GNUNET_GenericReturnValue 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_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_log(kind,...)
#define GNUNET_MIN(a, b)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_FS_meta_data_merge(struct GNUNET_FS_MetaData *md, const struct GNUNET_FS_MetaData *in)
Extend metadata.
Definition: meta_data.c:360
struct GNUNET_FS_MetaData * GNUNET_FS_meta_data_create()
Create a fresh struct FS_MetaData token.
Definition: meta_data.c:131
struct GNUNET_FS_MetaData * GNUNET_FS_meta_data_duplicate(const struct GNUNET_FS_MetaData *md)
Duplicate a struct GNUNET_FS_MetaData.
Definition: meta_data.c:531
void GNUNET_FS_meta_data_destroy(struct GNUNET_FS_MetaData *md)
Free meta data.
Definition: meta_data.c:170
struct GNUNET_FS_MetaData * GNUNET_FS_meta_data_deserialize(const char *input, size_t size)
Deserialize meta-data.
Definition: meta_data.c:889
GNUNET_MQ_Error
Error codes for the queue.
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:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#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:62
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
#define GNUNET_MESSAGE_TYPE_FS_START_SEARCH
Client asks FS service to start a (keyword) search.
#define GNUNET_MESSAGE_TYPE_FS_PUT
P2P response with content or active migration of content.
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:1299
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
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:72
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:436
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:531
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:603
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Response from FS service with a result for a previous FS search.
Definition: fs.h:356
uint32_t type
Type of the block (in big endian).
Definition: fs.h:365
struct GNUNET_TIME_AbsoluteNBO expiration
When does this result expire?
Definition: fs.h:370
struct GNUNET_MessageHeader header
Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
Definition: fs.h:360
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:59
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:64
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:104
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
struct GNUNET_FS_SearchResult * search
Associated search (used when downloading files based on search results), or NULL for none.
Definition: fs_api.h:1770
char * serialization
Random portion of filename we use for syncing state of this download.
Definition: fs_api.h:1816
struct GNUNET_FS_Handle * h
Global FS context.
Definition: fs_api.h:1748
struct TopLevelActivity * top
Our top-level activity entry (if we are top-level, otherwise NULL).
Definition: fs_api.h:1753
Master context for most FS operations.
Definition: fs_api.h:1070
enum GNUNET_FS_Flags flags
General flags.
Definition: fs_api.h:1162
struct GNUNET_TIME_Relative avg_block_latency
Average time we take for a single request to be satisfied.
Definition: fs_api.h:1147
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: fs_api.h:1074
Meta data to associate with a file, directory or namespace.
Definition: meta_data.c:96
Argument given to the progress callback with information about what is going on.
void * cctx
Client context pointer (set the last time by the client for this operation; initially NULL on START/R...
Handle for controlling a search.
Definition: fs_api.h:1511
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:1559
char * emsg
Error message (non-NULL if this operation failed).
Definition: fs_api.h:1551
struct SearchRequestEntry * requests
Per-keyword information for a keyword search.
Definition: fs_api.h:1565
char * serialization
Name of the file on disk we use for persistence.
Definition: fs_api.h:1546
void * client_info
Pointer we keep for the client.
Definition: fs_api.h:1541
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:1531
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:1583
struct GNUNET_TIME_Relative reconnect_backoff
How long to wait before we try to reconnect to FS service?
Definition: fs_api.h:1575
enum GNUNET_FS_SearchOptions options
Options for the search.
Definition: fs_api.h:1598
uint32_t anonymity
Anonymity level for the search.
Definition: fs_api.h:1588
struct TopLevelActivity * top
Our top-level activity entry (if we are top-level, otherwise NULL).
Definition: fs_api.h:1520
struct GNUNET_FS_Uri * uri
List of keywords that we're looking for.
Definition: fs_api.h:1525
uint32_t mandatory_count
Number of mandatory keywords in this query.
Definition: fs_api.h:1593
struct GNUNET_FS_Handle * h
Handle to the global FS context.
Definition: fs_api.h:1515
struct GNUNET_MQ_Handle * mq
Connection to the FS service.
Definition: fs_api.h:1536
struct GNUNET_TIME_Absolute start_time
When did we start?
Definition: fs_api.h:1570
Information we store for each search result.
Definition: fs_api.h:499
uint32_t optional_support
Number of optional keywords under which this result was also found.
Definition: fs_api.h:602
struct GNUNET_FS_DownloadContext * download
ID of an associated download based on this search result (or NULL for none).
Definition: fs_api.h:546
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:552
void * client_info
Client info for this search result.
Definition: fs_api.h:534
struct GNUNET_FS_DownloadContext * probe_ctx
ID of a job that is currently probing this results' availability (NULL if we are not currently probin...
Definition: fs_api.h:540
uint32_t availability_trials
Number of availability trials that we have performed for this search result.
Definition: fs_api.h:613
struct GNUNET_FS_Uri * uri
URI to which this search result refers to.
Definition: fs_api.h:524
uint8_t * keyword_bitmap
Bitmap that specifies precisely which keywords have been matched already.
Definition: fs_api.h:562
struct GNUNET_FS_Handle * h
File-sharing context this result belongs to.
Definition: fs_api.h:503
struct GNUNET_HashCode key
Key for the search result based on the URI.
Definition: fs_api.h:567
char * serialization
Name under which this search result is stored on disk.
Definition: fs_api.h:557
uint32_t anonymity
Anonymity level to use for probes using this search result.
Definition: fs_api.h:589
uint32_t availability_success
Number of availability tests that have succeeded for this result.
Definition: fs_api.h:607
struct GNUNET_FS_MetaData * meta
Metadata for the search result.
Definition: fs_api.h:529
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:519
struct GNUNET_TIME_Absolute probe_active_time
When did the current probe become active?
Definition: fs_api.h:579
struct GNUNET_TIME_Relative remaining_probe_time
How much longer should we run the current probe before giving up?
Definition: fs_api.h:584
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:596
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:574
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:167
struct GNUNET_FS_Uri::@13::@14 ksk
union GNUNET_FS_Uri::@13 data
struct GNUNET_FS_Uri::@13::@15 sks
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:171
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:212
A 512-bit hashcode.
Message handler for a specific message type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Context for "get_result_present".
Definition: fs_search.c:151
const struct GNUNET_FS_Uri * uri
The URI we're looking for.
Definition: fs_search.c:155
struct GNUNET_FS_SearchResult * sr
Where to store a pointer to the search result struct if we found a match.
Definition: fs_search.c:161
Closure for build_result_set().
Definition: fs_search.c:1015
unsigned int put_cnt
How many entries can we store to xoff.
Definition: fs_search.c:1019
struct GNUNET_HashCode * xoff
Where to store the keys.
Definition: fs_search.c:1029
unsigned int keyword_offset
Keyword offset the search result must match (0 for SKS)
Definition: fs_search.c:1039
struct GNUNET_FS_SearchContext * sc
Search context we are iterating for.
Definition: fs_search.c:1034
unsigned int skip_cnt
How many entries should we skip.
Definition: fs_search.c:1024
Message sent from a GNUnet (fs) search activity to the gnunet-service-fs to start a search.
Definition: fs.h:270
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:307
uint32_t type
Type of the content that we're looking for.
Definition: fs.h:290
struct GNUNET_HashCode query
Hash of the public key for UBLOCKs; Hash of the CHK-encoded block for DBLOCKS and IBLOCKS.
Definition: fs.h:313
uint32_t anonymity_level
Desired anonymity level, big-endian.
Definition: fs.h:295
uint32_t options
Bitmask with options.
Definition: fs.h:285
Information we keep for each keyword in a keyword search.
Definition: fs_api.h:1472
int mandatory
Is this keyword a mandatory keyword (started with '+')?
Definition: fs_api.h:1503
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:1497
struct GNUNET_CRYPTO_EcdsaPublicKey dpub
Derived public key, hashes to 'uquery'.
Definition: fs_api.h:1481
char * keyword
The original keyword, used to derive the key (for decrypting the UBlock).
Definition: fs_api.h:1487
struct GNUNET_HashCode uquery
Hash of the public key, also known as the query.
Definition: fs_api.h:1476
universal block for keyword and namespace search results
Definition: block_fs.h:54
struct GNUNET_CRYPTO_EcdsaPublicKey verification_key
Public key used to sign this block.
Definition: block_fs.h:68
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model