search.c

来自「GNUnet是一个安全的点对点网络框架」· C语言 代码 · 共 573 行 · 第 1/2 页

C
573
字号
    }  GNUNET_meta_data_destroy (fi.meta);  GNUNET_ECRS_uri_destroy (fi.uri);  return ret;}/** * Process replies received in response to our * queries.  Verifies, decrypts and passes valid * replies to the callback. * * @return GNUNET_SYSERR if the entry is malformed */static intreceive_response_callback (const GNUNET_HashCode * key,                           const GNUNET_DatastoreValue * value,                           void *cls, unsigned long long uid){  struct PendingSearch *ps = cls;  struct GNUNET_ECRS_SearchContext *sqc = ps->context;  struct GNUNET_GE_Context *ectx = sqc->ectx;  unsigned int type;  GNUNET_ECRS_FileInfo fi;  unsigned int size;  int ret;  GNUNET_HashCode query;  GNUNET_CronTime expiration;  expiration = GNUNET_ntohll (value->expiration_time);  if (expiration < GNUNET_get_time ())    return GNUNET_OK;           /* expired, ignore! */  type = ntohl (value->type);  size = ntohl (value->size) - sizeof (GNUNET_DatastoreValue);#if DEBUG_SEARCH  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "Search received reply of type %u and size %u.\n", type,                 size);#endif  if (GNUNET_OK !=      GNUNET_EC_file_block_check_and_get_query (size,                                                (const GNUNET_EC_DBlock *)                                                &value[1], GNUNET_YES,                                                &query))    {      GNUNET_GE_BREAK_OP (NULL, 0);      return GNUNET_SYSERR;    }  if (!((0 == memcmp (&query,                      (GNUNET_HashCode *) & ps[1], sizeof (GNUNET_HashCode)))        && ((ps->type == type) || (ps->type == GNUNET_ECRS_BLOCKTYPE_ANY))        && (GNUNET_YES ==            GNUNET_EC_is_block_applicable_for_query (type, size,                                                     (const GNUNET_EC_DBlock                                                      *) &value[1], &query,                                                     ps->keyCount,                                                     (GNUNET_HashCode *) &                                                     ps[1]))))    {      return GNUNET_OK;         /* not a match */    }  switch (type)    {    case GNUNET_ECRS_BLOCKTYPE_KEYWORD:      {        GNUNET_EC_KBlock *kb;        const char *dstURI;#if DEBUG_SEARCH        GNUNET_EncName enc;#endif        int j;        if (size < sizeof (GNUNET_EC_KBlock))          {            GNUNET_GE_BREAK_OP (NULL, 0);            return GNUNET_SYSERR;          }        kb = GNUNET_malloc (size);        memcpy (kb, &value[1], size);#if DEBUG_SEARCH        IF_GELOG (ectx,                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |                  GNUNET_GE_USER, GNUNET_hash_to_enc (&ps->decryptKey, &enc));        GNUNET_GE_LOG (ectx,                       GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |                       GNUNET_GE_USER,                       "Decrypting KBlock with key %s.\n", &enc);#endif        GNUNET_ECRS_decryptInPlace (&ps->decryptKey,                                    &kb[1], size - sizeof (GNUNET_EC_KBlock));        j = sizeof (GNUNET_EC_KBlock);        while ((j < size) && (((const char *) kb)[j] != '\0'))          j++;        if (j == size)          {            GNUNET_GE_BREAK_OP (ectx, 0);       /* kblock malformed */            GNUNET_free (kb);            return GNUNET_SYSERR;          }        dstURI = (const char *) &kb[1];        j++;        fi.meta = GNUNET_meta_data_deserialize (ectx,                                                &((const char *)                                                  kb)[j], size - j);        if (fi.meta == NULL)          {            GNUNET_GE_BREAK_OP (ectx, 0);       /* kblock malformed */            GNUNET_free (kb);            return GNUNET_SYSERR;          }        fi.uri = GNUNET_ECRS_string_to_uri (ectx, dstURI);        if (fi.uri == NULL)          {            GNUNET_GE_BREAK_OP (ectx, 0);       /* kblock malformed */            GNUNET_meta_data_destroy (fi.meta);            GNUNET_free (kb);            return GNUNET_SYSERR;          }        if (sqc->spcb != NULL)          {            ret = sqc->spcb (&fi,                             &ps->decryptKey, GNUNET_NO, sqc->spcbClosure);            if (ret == GNUNET_SYSERR)              sqc->aborted = GNUNET_YES;          }        else          ret = GNUNET_OK;        GNUNET_ECRS_uri_destroy (fi.uri);        GNUNET_meta_data_destroy (fi.meta);        GNUNET_free (kb);        return ret;      }    case GNUNET_ECRS_BLOCKTYPE_SIGNED:      {        GNUNET_EC_SBlock *sb;        int ret;        if (size < sizeof (GNUNET_EC_SBlock))          {            GNUNET_GE_BREAK_OP (ectx, 0);       /* sblock malformed */            return GNUNET_SYSERR;          }        sb = GNUNET_malloc (size);        memcpy (sb, &value[1], size);        GNUNET_ECRS_decryptInPlace (&ps->decryptKey,                                    &sb[1], size - sizeof (GNUNET_EC_SBlock));        ret = process_sblock_result (sb, &ps->decryptKey, size, sqc);        GNUNET_free (sb);        return ret;      }    case GNUNET_ECRS_BLOCKTYPE_KEYWORD_SIGNED:      {        GNUNET_EC_KSBlock *kb;        int ret;        if (size < sizeof (GNUNET_EC_KSBlock))          {            GNUNET_GE_BREAK_OP (ectx, 0);       /* ksblock malformed */            return GNUNET_SYSERR;          }        kb = GNUNET_malloc (size);        memcpy (kb, &value[1], size);        GNUNET_ECRS_decryptInPlace (&ps->decryptKey,                                    &kb->sblock,                                    size - sizeof (GNUNET_EC_KBlock) -                                    sizeof (unsigned int));        ret =          process_sblock_result (&kb->sblock, &ps->decryptKey,                                 size - sizeof (GNUNET_EC_KSBlock) +                                 sizeof (GNUNET_EC_SBlock), sqc);        GNUNET_free (kb);        return ret;      }    default:      GNUNET_GE_BREAK_OP (ectx, 0);      break;    }                           /* end switch */  return GNUNET_OK;}/** * Start search for content. * * @param uri specifies the search parameters * @param uri set to the URI of the uploaded file */struct GNUNET_ECRS_SearchContext *GNUNET_ECRS_search_start (struct GNUNET_GE_Context *ectx,                          struct GNUNET_GC_Configuration *cfg,                          struct GNUNET_FS_SearchContext *sc,                          const struct GNUNET_ECRS_URI *uri,                          unsigned int anonymityLevel,                          GNUNET_ECRS_SearchResultProcessor spcb,                          void *spcbClosure){  struct GNUNET_ECRS_SearchContext *ctx;  if (GNUNET_YES == GNUNET_ECRS_uri_test_ksk (uri))    {      if (1 != GNUNET_ECRS_uri_get_keyword_count_from_ksk (uri))        return NULL;    }  else    {      if (GNUNET_YES != GNUNET_ECRS_uri_test_sks (uri))        return NULL;    }  ctx = GNUNET_malloc (sizeof (struct GNUNET_ECRS_SearchContext));  ctx->start = GNUNET_get_time ();  ctx->anonymityLevel = anonymityLevel;  ctx->ectx = ectx;  ctx->cfg = cfg;  ctx->queries = NULL;  ctx->spcb = spcb;  ctx->spcbClosure = spcbClosure;  ctx->aborted = GNUNET_NO;  ctx->sctx = sc == NULL ? GNUNET_FS_create_search_context (ectx, cfg) : sc;  if (ctx->sctx == NULL)    {      GNUNET_free (ctx);      return NULL;    }  ctx->my_sctx = (sc == NULL);  add_search_for_uri (uri, ctx);  return ctx;}/** * Stop search for content. * * @param uri specifies the search parameters * @param uri set to the URI of the uploaded file */voidGNUNET_ECRS_search_stop (struct GNUNET_ECRS_SearchContext *ctx){  struct PendingSearch *pos;  while (ctx->queries != NULL)    {      pos = ctx->queries;      ctx->queries = pos->next;      if (!ctx->my_sctx)        GNUNET_FS_stop_search (ctx->sctx, &receive_response_callback, pos);      GNUNET_free (pos);    }  if (ctx->my_sctx)    GNUNET_FS_destroy_search_context (ctx->sctx);  GNUNET_free (ctx);}/** * Search for content. * * @param timeout how long to wait (relative) * @param uri specifies the search parameters * @param uri set to the URI of the uploaded file */intGNUNET_ECRS_search (struct GNUNET_GE_Context *ectx,                    struct GNUNET_GC_Configuration *cfg,                    const struct GNUNET_ECRS_URI *uri,                    unsigned int anonymityLevel,                    GNUNET_ECRS_SearchResultProcessor spcb,                    void *spcbClosure, GNUNET_ECRS_TestTerminate tt,                    void *ttClosure){  struct GNUNET_ECRS_SearchContext *ctx;  ctx =    GNUNET_ECRS_search_start (ectx, cfg, NULL,                              uri, anonymityLevel, spcb, spcbClosure);  if (ctx == NULL)    return GNUNET_SYSERR;  while (((NULL == tt) || (GNUNET_OK == tt (ttClosure)))         && (GNUNET_NO == GNUNET_shutdown_test ())         && (ctx->aborted == GNUNET_NO))    GNUNET_thread_sleep (100 * GNUNET_CRON_MILLISECONDS);  GNUNET_ECRS_search_stop (ctx);  return GNUNET_OK;}/* end of search.c */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?