#include "gnunet_fs_service.h"
#include "gnunet_protocols.h"
#include "fs_api.h"
+#include "fs_publish_ublock.h"
/**
* call the callback.
*
* @param pi structure to fill in
+ * @param h file-sharing handle
* @param sc overall search context
* @return value returned by the callback
*/
void *
GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
+ struct GNUNET_FS_Handle *h,
struct GNUNET_FS_SearchContext *sc)
{
void *ret;
pi->value.search.sc = sc;
- pi->value.search.cctx = sc->client_info;
+ pi->value.search.cctx = (NULL != sc) ? sc->client_info : NULL;
pi->value.search.pctx =
- (NULL == sc->psearch_result) ? NULL : sc->psearch_result->client_info;
- pi->value.search.query = sc->uri;
- pi->value.search.duration =
- GNUNET_TIME_absolute_get_duration (sc->start_time);
- pi->value.search.anonymity = sc->anonymity;
- ret = sc->h->upcb (sc->h->upcb_cls, pi);
+ ((NULL == sc) || (NULL == sc->psearch_result))
+ ? NULL
+ : sc->psearch_result->client_info;
+ pi->value.search.query = (NULL != sc) ? sc->uri : NULL;
+ pi->value.search.duration = (NULL != sc)
+ ? GNUNET_TIME_absolute_get_duration (sc->start_time)
+ : GNUNET_TIME_UNIT_ZERO;
+ pi->value.search.anonymity = (NULL != sc) ? sc->anonymity : 0;
+ pi->fsh = h;
+ ret = h->upcb (h->upcb_cls, pi);
return ret;
}
pi.value.search.specifics.result.uri = sr->uri;
pi.value.search.specifics.result.result = sr;
pi.value.search.specifics.result.applicability_rank = sr->optional_support;
- sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
}
pi.value.search.specifics.update.applicability_rank = sr->optional_support;
pi.value.search.specifics.update.current_probe_time
= GNUNET_TIME_absolute_get_duration (sr->probe_active_time);
- sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
}
pi.value.search.specifics.update.applicability_rank = sr->optional_support;
pi.value.search.specifics.update.current_probe_time
= GNUNET_TIME_absolute_get_duration (sr->probe_active_time);
- sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->sc);
+ sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->h, sr->sc);
GNUNET_FS_search_start_probe_ (sr);
}
return;
if (NULL != sr->download)
return;
- if (0 == (sr->sc->h->flags & GNUNET_FS_FLAGS_DO_PROBES))
+ if (0 == (sr->h->flags & GNUNET_FS_FLAGS_DO_PROBES))
return;
if (sr->availability_trials > AVAILABILITY_TRIALS_MAX)
return;
(unsigned long long) off,
sr);
sr->remaining_probe_time =
- GNUNET_TIME_relative_multiply (sr->sc->h->avg_block_latency,
+ GNUNET_TIME_relative_multiply (sr->h->avg_block_latency,
2 * (1 + sr->availability_trials));
sr->probe_ctx =
- GNUNET_FS_download_start (sr->sc->h, sr->uri, sr->meta, NULL, NULL, off,
- len, sr->sc->anonymity,
+ GNUNET_FS_download_start (sr->h, sr->uri, sr->meta, NULL, NULL, off,
+ len, sr->anonymity,
GNUNET_FS_DOWNLOAD_NO_TEMPORARIES |
GNUNET_FS_DOWNLOAD_IS_PROBE, sr, NULL);
sr->probe_ping_task
}
+/**
+ * Start download probes for the given search result.
+ *
+ * @param h file-sharing handle to use for the operation
+ * @param uri URI to probe
+ * @param meta meta data associated with the URI
+ * @param client_info client info pointer to use for associated events
+ * @param anonymity anonymity level to use for the probes
+ * @return the search result handle to access the probe activity
+ */
+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)
+{
+ struct GNUNET_FS_SearchResult *sr;
+
+ GNUNET_assert (NULL != h);
+ sr = GNUNET_new (struct GNUNET_FS_SearchResult);
+ sr->h = h;
+ sr->uri = GNUNET_FS_uri_dup (uri);
+ sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
+ sr->client_info = client_info;
+ sr->anonymity = anonymity;
+ GNUNET_FS_search_start_probe_ (sr);
+ return sr;
+}
+
+
+/**
+ * Stop probing activity associated with a search result.
+ *
+ * @param sr search result
+ */
+static void
+GNUNET_FS_search_stop_probe_ (struct GNUNET_FS_SearchResult *sr)
+{
+ if (NULL != sr->probe_ctx)
+ {
+ GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
+ sr->probe_ctx = NULL;
+ }
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task)
+ {
+ GNUNET_SCHEDULER_cancel (sr->probe_ping_task);
+ sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
+ {
+ GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
+ sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+}
+
+
+/**
+ * Stop probe activity. Must ONLY be used on values
+ * returned from 'GNUNET_FS_probe'.
+ *
+ * @param sr search result to stop probing for (freed)
+ * @return the value of the 'client_info' pointer
+ */
+void *
+GNUNET_FS_probe_stop (struct GNUNET_FS_SearchResult *sr)
+{
+ void *client_info;
+
+ GNUNET_assert (NULL == sr->sc);
+ GNUNET_FS_search_stop_probe_ (sr);
+ GNUNET_FS_uri_destroy (sr->uri);
+ GNUNET_CONTAINER_meta_data_destroy (sr->meta);
+ client_info = sr->client_info;
+ GNUNET_free (sr);
+ return client_info;
+}
+
+
/**
* We have received a KSK result. Check how it fits in with the
* overall query and notify the client accordingly.
if (NULL == sr)
{
sr = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchResult));
+ sr->h = sc->h;
sr->sc = sc;
+ sr->anonymity = sc->anonymity;
sr->uri = GNUNET_FS_uri_dup (uri);
sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
sr->mandatory_missing = sc->mandatory_count;
(void *) uri))
return; /* duplicate result */
sr = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchResult));
+ sr->h = sc->h;
sr->sc = sc;
+ sr->anonymity = sc->anonymity;
sr->uri = GNUNET_FS_uri_dup (uri);
sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
sr->key = key;
* given ciphertext block.
*
* @param sc search context with the keywords
- * @param verification_key public key to use to lookup the keyword
+ * @param dpub derived public key used for the search
* @param edata encrypted data
* @param edata_size number of bytes in 'edata' (and 'data')
* @param data where to store the plaintext
*/
static int
decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc,
- const struct GNUNET_FS_PseudonymIdentifier *verification_key,
+ const struct GNUNET_CRYPTO_EccPublicKey *dpub,
const void *edata,
size_t edata_size,
char *data)
{
- struct GNUNET_HashCode q;
- struct GNUNET_CRYPTO_AesSessionKey skey;
- struct GNUNET_CRYPTO_AesInitializationVector iv;
- int i;
+ const struct GNUNET_CRYPTO_EccPrivateKey *anon;
+ struct GNUNET_CRYPTO_EccPublicKey anon_pub;
+ unsigned int i;
- GNUNET_CRYPTO_hash (verification_key,
- sizeof (struct GNUNET_FS_PseudonymIdentifier),
- &q);
/* find key */
for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
- if (0 == memcmp (&q, &sc->requests[i].uquery, sizeof (struct GNUNET_HashCode)))
+ if (0 == memcmp (dpub,
+ &sc->requests[i].dpub,
+ sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
break;
if (i == sc->uri->data.ksk.keywordCount)
{
return GNUNET_SYSERR;
}
/* decrypt */
- GNUNET_CRYPTO_hash_to_aes_key (&sc->requests[i].ukey, &skey, &iv);
- if (-1 ==
- GNUNET_CRYPTO_aes_decrypt (edata, edata_size, &skey,
- &iv, data))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
+ anon = GNUNET_CRYPTO_ecc_key_get_anonymous ();
+ GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub);
+ GNUNET_FS_ublock_decrypt_ (edata, edata_size,
+ &anon_pub,
+ sc->requests[i].keyword,
+ data);
return i;
}
{
size_t len = size - sizeof (struct UBlock);
char pt[len];
- struct GNUNET_CRYPTO_AesSessionKey skey;
- struct GNUNET_CRYPTO_AesInitializationVector iv;
struct GNUNET_FS_Uri *uri;
struct GNUNET_CONTAINER_MetaData *meta;
const char *id;
const char *uris;
size_t off;
char *emsg;
- struct GNUNET_HashCode key;
- struct GNUNET_HashCode id_hash;
- struct GNUNET_HashCode ns_hash;
- char *identifier;
/* decrypt */
- identifier = sc->uri->data.sks.identifier;
- GNUNET_CRYPTO_hash (identifier, strlen (identifier), &id_hash);
- GNUNET_CRYPTO_hash (&sc->uri->data.sks.ns,
- sizeof (sc->uri->data.sks.ns), &ns_hash);
- GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key);
- GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv);
- if (-1 == GNUNET_CRYPTO_aes_decrypt (&ub[1], len, &skey, &iv, pt))
- {
- GNUNET_break (0);
- return;
- }
+ GNUNET_FS_ublock_decrypt_ (&ub[1], len,
+ &sc->uri->data.sks.ns,
+ sc->uri->data.sks.identifier,
+ pt);
/* parse */
if (0 == (off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris)))
{
struct MessageBuilderContext mbc;
size_t msize;
struct SearchMessage *sm;
- const char *identifier;
- struct GNUNET_HashCode key;
- struct GNUNET_HashCode signing_key;
- struct GNUNET_HashCode ns_hash;
- struct GNUNET_HashCode id_hash;
- struct GNUNET_FS_PseudonymIdentifier verification_key;
+ struct GNUNET_CRYPTO_EccPublicKey dpub;
unsigned int sqms;
uint32_t options;
sm->type = htonl (GNUNET_BLOCK_TYPE_FS_UBLOCK);
sm->anonymity_level = htonl (sc->anonymity);
memset (&sm->target, 0, sizeof (struct GNUNET_HashCode));
-
- identifier = sc->uri->data.sks.identifier;
- GNUNET_CRYPTO_hash (identifier, strlen (identifier), &id_hash);
- GNUNET_CRYPTO_hash (&sc->uri->data.sks.ns,
- sizeof (sc->uri->data.sks.ns), &ns_hash);
- GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key);
- GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &signing_key);
- GNUNET_FS_pseudonym_derive_verification_key (&sc->uri->data.sks.ns,
- &signing_key,
- &verification_key);
- GNUNET_CRYPTO_hash (&verification_key,
- sizeof (verification_key),
+ GNUNET_CRYPTO_ecc_public_key_derive (&sc->uri->data.sks.ns,
+ sc->uri->data.sks.identifier,
+ &dpub);
+ GNUNET_CRYPTO_hash (&dpub,
+ sizeof (dpub),
&sm->query);
mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode);
sqms = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map);
}
GNUNET_FS_search_sync_ (sc);
pi.status = GNUNET_FS_STATUS_SEARCH_START;
- sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
return sc;
}
{
unsigned int i;
const char *keyword;
- struct GNUNET_HashCode signing_key;
- struct GNUNET_FS_PseudonymHandle *ph;
- struct GNUNET_FS_PseudonymIdentifier anon;
- struct GNUNET_FS_PseudonymIdentifier verification_key;
+ const struct GNUNET_CRYPTO_EccPrivateKey *anon;
+ struct GNUNET_CRYPTO_EccPublicKey anon_pub;
+ struct SearchRequestEntry *sre;
GNUNET_assert (NULL == sc->client);
if (GNUNET_FS_uri_test_ksk (sc->uri))
{
GNUNET_assert (0 != sc->uri->data.ksk.keywordCount);
- ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle ();
- GNUNET_FS_pseudonym_get_identifier (ph, &anon);
- GNUNET_FS_pseudonym_destroy (ph);
+ anon = GNUNET_CRYPTO_ecc_key_get_anonymous ();
+ GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub);
sc->requests =
GNUNET_malloc (sizeof (struct SearchRequestEntry) *
sc->uri->data.ksk.keywordCount);
for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
{
keyword = &sc->uri->data.ksk.keywords[i][1];
- GNUNET_CRYPTO_hash (keyword, strlen (keyword), &sc->requests[i].ukey);
- GNUNET_CRYPTO_hash (&sc->requests[i].ukey, sizeof (struct GNUNET_HashCode), &signing_key);
- GNUNET_FS_pseudonym_derive_verification_key (&anon,
- &signing_key,
- &verification_key);
- GNUNET_CRYPTO_hash (&verification_key, sizeof (struct GNUNET_FS_PseudonymIdentifier),
- &sc->requests[i].uquery);
- sc->requests[i].mandatory = (sc->uri->data.ksk.keywords[i][0] == '+');
- if (sc->requests[i].mandatory)
+ sre = &sc->requests[i];
+ sre->keyword = GNUNET_strdup (keyword);
+ GNUNET_CRYPTO_ecc_public_key_derive (&anon_pub,
+ keyword,
+ &sre->dpub);
+ GNUNET_CRYPTO_hash (&sre->dpub,
+ sizeof (struct GNUNET_CRYPTO_EccPublicKey),
+ &sre->uquery);
+ sre->mandatory = (sc->uri->data.ksk.keywords[i][0] == '+');
+ if (sre->mandatory)
sc->mandatory_count++;
- sc->requests[i].results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
+ sre->results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
}
}
sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg);
pi.value.search.specifics.result_suspend.cctx = sr->client_info;
pi.value.search.specifics.result_suspend.meta = sr->meta;
pi.value.search.specifics.result_suspend.uri = sr->uri;
- sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
GNUNET_break (NULL == sr->client_info);
GNUNET_free_non_null (sr->serialization);
GNUNET_FS_uri_destroy (sr->uri);
GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
&search_result_suspend, sc);
pi.status = GNUNET_FS_STATUS_SEARCH_SUSPEND;
- sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
GNUNET_break (NULL == sc->client_info);
if (sc->task != GNUNET_SCHEDULER_NO_TASK)
GNUNET_SCHEDULER_cancel (sc->task);
{
GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri));
for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
+ {
GNUNET_CONTAINER_multihashmap_destroy (sc->requests[i].results);
+ GNUNET_free (sc->requests[i].keyword);
+ }
}
GNUNET_free_non_null (sc->requests);
GNUNET_free_non_null (sc->emsg);
GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
&search_result_freeze_probes, sc);
pi.status = GNUNET_FS_STATUS_SEARCH_PAUSED;
- sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
}
do_reconnect (sc, NULL);
GNUNET_FS_search_sync_ (sc);
pi.status = GNUNET_FS_STATUS_SEARCH_CONTINUED;
- sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
&search_result_resume_probes, sc);
}
struct GNUNET_FS_SearchResult *sr = value;
struct GNUNET_FS_ProgressInfo pi;
- if (NULL != sr->probe_ctx)
- {
- GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
- sr->probe_ctx = NULL;
- }
- if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task)
- {
- GNUNET_SCHEDULER_cancel (sr->probe_ping_task);
- sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
- {
- GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
- sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
- }
+ GNUNET_FS_search_stop_probe_ (sr);
if (NULL != sr->download)
{
pi.value.search.specifics.result_stopped.cctx = sr->client_info;
pi.value.search.specifics.result_stopped.meta = sr->meta;
pi.value.search.specifics.result_stopped.uri = sr->uri;
- sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->h, sc);
return GNUNET_OK;
}
GNUNET_free (sc->serialization);
}
pi.status = GNUNET_FS_STATUS_SEARCH_STOPPED;
- sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc->h, sc);
GNUNET_break (NULL == sc->client_info);
if (GNUNET_SCHEDULER_NO_TASK != sc->task)
GNUNET_SCHEDULER_cancel (sc->task);