gnunet-android

GNUnet for Android
Log | Files | Refs | README

gnunet_dht_service.h (18985B)


      1 /*
      2       This file is part of GNUnet
      3       Copyright (C) 2004-2013, 2016, 2022 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  */
     20 
     21 /**
     22  * @addtogroup Backbone
     23  * @{
     24  * @addtogroup dht_libs  DHT and support libraries
     25  * @{
     26  *
     27  * @author Christian Grothoff
     28  *
     29  * @file
     30  * API to the DHT service
     31  *
     32  * @defgroup dht  DHT service
     33  * Distributed Hash Table
     34  *
     35  * @see [Documentation](https://gnunet.org/developer-handbook-dht)
     36  *
     37  * @{
     38  */
     39 
     40 #ifndef GNUNET_DHT_SERVICE_H
     41 #define GNUNET_DHT_SERVICE_H
     42 
     43 
     44 #include "gnunet_util_lib.h"
     45 #include "gnunet_block_lib.h"
     46 
     47 #ifdef __cplusplus
     48 extern "C"
     49 {
     50 #if 0                           /* keep Emacsens' auto-indent happy */
     51 }
     52 #endif
     53 #endif
     54 
     55 
     56 /**
     57  * Default republication frequency for stored data in the DHT.
     58  */
     59 #define GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY GNUNET_TIME_relative_multiply ( \
     60           GNUNET_TIME_UNIT_MINUTES, 60)
     61 
     62 
     63 /**
     64  * Maximum allowed replication level for all requests.
     65  */
     66 #define GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL 16
     67 
     68 
     69 /**
     70  * Connection to the DHT service.
     71  */
     72 struct GNUNET_DHT_Handle;
     73 
     74 /**
     75  * Handle to control a get operation.
     76  */
     77 struct GNUNET_DHT_GetHandle;
     78 
     79 /**
     80  * Handle to control a find peer operation.
     81  */
     82 struct GNUNET_DHT_FindPeerHandle;
     83 
     84 
     85 /**
     86  * Options for routing.
     87  */
     88 enum GNUNET_DHT_RouteOption
     89 {
     90   /**
     91    * Default.  Do nothing special.
     92    */
     93   GNUNET_DHT_RO_NONE = 0,
     94 
     95   /**
     96    * Each peer along the way should process the request (otherwise
     97    * only peers locally closest to the key when the random walk
     98    * is over should look at it).
     99    */
    100   GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE = 1,
    101 
    102   /**
    103    * We should keep track of the route that the message
    104    * took in the P2P network.
    105    */
    106   GNUNET_DHT_RO_RECORD_ROUTE = 2,
    107 
    108   /**
    109    * Approximate results are fine.
    110    */
    111   GNUNET_DHT_RO_FIND_APPROXIMATE = 4,
    112 
    113   /**
    114    * Flag set if the path was truncated.
    115    */
    116   GNUNET_DHT_RO_TRUNCATED = 8,
    117 
    118   /**
    119    * Flag given to monitors if this was the last hop for a GET/PUT.
    120    * This is only used for internal processing.
    121    */
    122   GNUNET_DHT_RO_LAST_HOP = 32768
    123 };
    124 
    125 
    126 GNUNET_NETWORK_STRUCT_BEGIN
    127 
    128 /**
    129  * Message signed by a peer when doing path tracking.
    130  */
    131 struct GNUNET_DHT_HopSignature
    132 {
    133   /**
    134    * Must be #GNUNET_SIGNATURE_PURPOSE_DHT_HOP.
    135    */
    136   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    137 
    138   /**
    139    * Expiration time of the block.
    140    */
    141   struct GNUNET_TIME_AbsoluteNBO expiration_time;
    142 
    143   /**
    144    * Hash over the payload of the block.
    145    */
    146   struct GNUNET_HashCode h_data GNUNET_PACKED;
    147 
    148   /**
    149    * Previous hop the message was received from.  All zeros
    150    * if this peer was the initiator.
    151    */
    152   struct GNUNET_PeerIdentity pred;
    153 
    154   /**
    155    * Next hop the message was forwarded to.
    156    */
    157   struct GNUNET_PeerIdentity succ;
    158 };
    159 
    160 
    161 /**
    162  * A (signed) path tracking a block's flow through the DHT is represented by
    163  * an array of path elements, each consisting of a peer on the path and a
    164  * signature by which the peer affirms its routing decision.
    165  */
    166 struct GNUNET_DHT_PathElement
    167 {
    168   /**
    169    * Signature affirming the hop of type
    170    * #GNUNET_SIGNATURE_PURPOSE_DHT_HOP.
    171    */
    172   struct GNUNET_CRYPTO_EddsaSignature sig;
    173 
    174   /**
    175    * Previous peer on the path (matches "pred" in the signed field).
    176    *
    177    * The public key used to create the @e sig is in the *next* path element,
    178    * or is the sender of the message if this was the last path element.
    179    *
    180    * The "succ" field can be found in 'pred' if there are two more path
    181    * elements in the path, is the sender if there is only one more path
    182    * element, or the recipient if this was the last element on the path.
    183    */
    184   struct GNUNET_PeerIdentity pred;
    185 
    186 };
    187 
    188 
    189 GNUNET_NETWORK_STRUCT_END
    190 
    191 /**
    192  * Initialize the connection with the DHT service.
    193  *
    194  * @param cfg configuration to use
    195  * @param ht_len size of the internal hash table to use for
    196  *               processing multiple GET/FIND requests in parallel
    197  * @return NULL on error
    198  */
    199 struct GNUNET_DHT_Handle *
    200 GNUNET_DHT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
    201                     unsigned int ht_len);
    202 
    203 
    204 /**
    205  * Shutdown connection with the DHT service.
    206  *
    207  * @param handle connection to shut down
    208  */
    209 void
    210 GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle);
    211 
    212 
    213 /* *************** Standard API: get and put ******************* */
    214 
    215 
    216 /**
    217  * Opaque handle to cancel a PUT operation.
    218  */
    219 struct GNUNET_DHT_PutHandle;
    220 
    221 
    222 /**
    223  * Perform a PUT operation storing data in the DHT.
    224  *
    225  * @param handle handle to DHT service
    226  * @param key the key to store under
    227  * @param desired_replication_level estimate of how many
    228  *                nearest peers this request should reach
    229  * @param options routing options for this message
    230  * @param type type of the value
    231  * @param size number of bytes in @a data; must be less than 64k
    232  * @param data the data to store
    233  * @param exp desired expiration time for the value
    234  * @param cont continuation to call when done (transmitting request to service)
    235  *        You must not call #GNUNET_DHT_disconnect in this continuation
    236  * @param cont_cls closure for @a cont
    237  * @return handle to cancel the "PUT" operation, NULL on error
    238  *        (size too big)
    239  */
    240 struct GNUNET_DHT_PutHandle *
    241 GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
    242                 const struct GNUNET_HashCode *key,
    243                 uint32_t desired_replication_level,
    244                 enum GNUNET_DHT_RouteOption options,
    245                 enum GNUNET_BLOCK_Type type,
    246                 size_t size,
    247                 const void *data,
    248                 struct GNUNET_TIME_Absolute exp,
    249                 GNUNET_SCHEDULER_TaskCallback cont,
    250                 void *cont_cls);
    251 
    252 
    253 /**
    254  * Cancels a DHT PUT operation.  Note that the PUT request may still
    255  * go out over the network (we can't stop that); However, if the PUT
    256  * has not yet been sent to the service, cancelling the PUT will stop
    257  * this from happening (but there is no way for the user of this API
    258  * to tell if that is the case).  The only use for this API is to
    259  * prevent a later call to 'cont' from #GNUNET_DHT_put (e.g. because
    260  * the system is shutting down).
    261  *
    262  * @param ph put operation to cancel ('cont' will no longer be called)
    263  */
    264 void
    265 GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph);
    266 
    267 
    268 /**
    269  * Iterator called on each result obtained for a DHT
    270  * operation that expects a reply
    271  *
    272  * @param cls closure
    273  * @param exp when will this value expire
    274  * @param query_hash key of the query
    275  * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
    276  * @param get_path peers on reply path (or NULL if not recorded)
    277  *                 [0] = datastore's first neighbor, [length - 1] = local peer
    278  * @param get_path_length number of entries in @a get_path
    279  * @param put_path peers on the PUT path (or NULL if not recorded)
    280  *                 [0] = origin, [length - 1] = datastore
    281  * @param put_path_length number of entries in @a put_path,
    282  *        note that the last signature will be all zeros as
    283  *        we did not forward and thus did not sign!
    284  * @param type type of the result
    285  * @param size number of bytes in @a data
    286  * @param data pointer to the result data
    287  */
    288 typedef void
    289 (*GNUNET_DHT_GetIterator) (void *cls,
    290                            struct GNUNET_TIME_Absolute exp,
    291                            const struct GNUNET_HashCode *query_hash,
    292                            const struct GNUNET_PeerIdentity *trunc_peer,
    293                            const struct GNUNET_DHT_PathElement *get_path,
    294                            unsigned int get_path_length,
    295                            const struct GNUNET_DHT_PathElement *put_path,
    296                            unsigned int put_path_length,
    297                            enum GNUNET_BLOCK_Type type,
    298                            size_t size,
    299                            const void *data);
    300 
    301 
    302 /**
    303  * Perform an asynchronous GET operation on the DHT identified. See
    304  * also #GNUNET_BLOCK_evaluate.
    305  *
    306  * @param handle handle to the DHT service
    307  * @param type expected type of the response object
    308  * @param key the key to look up
    309  * @param desired_replication_level estimate of how many
    310                   nearest peers this request should reach
    311  * @param options routing options for this message
    312  * @param xquery extended query data (can be NULL, depending on type)
    313  * @param xquery_size number of bytes in @a xquery
    314  * @param iter function to call on each result
    315  * @param iter_cls closure for @a iter
    316  * @return handle to stop the async get
    317  */
    318 struct GNUNET_DHT_GetHandle *
    319 GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
    320                       enum GNUNET_BLOCK_Type type,
    321                       const struct GNUNET_HashCode *key,
    322                       uint32_t desired_replication_level,
    323                       enum GNUNET_DHT_RouteOption options,
    324                       const void *xquery,
    325                       size_t xquery_size,
    326                       GNUNET_DHT_GetIterator iter,
    327                       void *iter_cls);
    328 
    329 
    330 /**
    331  * Tell the DHT not to return any of the following known results
    332  * to this client.
    333  *
    334  * @param get_handle get operation for which results should be filtered
    335  * @param num_results number of results to be blocked that are
    336  *        provided in this call (size of the @a results array)
    337  * @param results array of hash codes over the `data` of the results
    338  *        to be blocked
    339  */
    340 void
    341 GNUNET_DHT_get_filter_known_results (struct GNUNET_DHT_GetHandle *get_handle,
    342                                      unsigned int num_results,
    343                                      const struct GNUNET_HashCode *results);
    344 
    345 /**
    346  * Stop async DHT-get.  Frees associated resources.
    347  *
    348  * @param get_handle GET operation to stop.
    349  */
    350 void
    351 GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle);
    352 
    353 
    354 /* *************** Extended API: monitor ******************* */
    355 
    356 /**
    357  * Handle to monitor requests
    358  */
    359 struct GNUNET_DHT_MonitorHandle;
    360 
    361 /**
    362  * Callback called on each GET request going through the DHT.
    363  *
    364  * @param cls Closure.
    365  * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
    366  * @param type The type of data in the request.
    367  * @param hop_count Hop count so far.
    368  * @param desired_replication_level Desired replication level.
    369  * @param key Key of the requested data.
    370  */
    371 typedef void
    372 (*GNUNET_DHT_MonitorGetCB) (void *cls,
    373                             enum GNUNET_DHT_RouteOption options,
    374                             enum GNUNET_BLOCK_Type type,
    375                             uint32_t hop_count,
    376                             uint32_t desired_replication_level,
    377                             const struct GNUNET_HashCode *key);
    378 
    379 
    380 /**
    381  * Callback called on each GET reply going through the DHT.
    382  *
    383  * @param cls Closure.
    384  * @param type The type of data in the result.
    385  * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
    386  * @param get_path Peers on GET path (or NULL if not recorded).
    387  *        note that the last signature will be all zeros as
    388  *        we did not forward and thus did not sign!
    389  * @param get_path_length number of entries in @a get_path.
    390  * @param put_path peers on the PUT path (or NULL if not recorded).
    391  * @param put_path_length number of entries in @a get_path.
    392  * @param exp Expiration time of the data.
    393  * @param key Key of the data.
    394  * @param data Pointer to the result data.
    395  * @param size Number of bytes in @a data.
    396  */
    397 typedef void
    398 (*GNUNET_DHT_MonitorGetRespCB) (void *cls,
    399                                 enum GNUNET_BLOCK_Type type,
    400                                 const struct GNUNET_PeerIdentity *trunc_peer,
    401                                 const struct GNUNET_DHT_PathElement *get_path,
    402                                 unsigned int get_path_length,
    403                                 const struct GNUNET_DHT_PathElement *put_path,
    404                                 unsigned int put_path_length,
    405                                 struct GNUNET_TIME_Absolute exp,
    406                                 const struct GNUNET_HashCode *key,
    407                                 const void *data,
    408                                 size_t size);
    409 
    410 
    411 /**
    412  * Callback called on each PUT request going through the DHT.
    413  *
    414  * @param cls Closure.
    415  * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
    416  * @param type The type of data in the request.
    417  * @param hop_count Hop count so far.
    418  * @param desired_replication_level Desired replication level.
    419  * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
    420  * @param path_length number of entries in @a path (or 0 if not recorded).
    421  * @param path peers on the PUT path (or NULL if not recorded).
    422  *        note that the last signature will be all zeros as
    423  *        we did not forward and thus did not sign!
    424  * @param exp Expiration time of the data.
    425  * @param key Key under which data is to be stored.
    426  * @param data Pointer to the data carried.
    427  * @param size Number of bytes in @a data.
    428  */
    429 typedef void
    430 (*GNUNET_DHT_MonitorPutCB) (void *cls,
    431                             enum GNUNET_DHT_RouteOption options,
    432                             enum GNUNET_BLOCK_Type type,
    433                             uint32_t hop_count,
    434                             uint32_t desired_replication_level,
    435                             const struct GNUNET_PeerIdentity *trunc_peer,
    436                             unsigned int path_length,
    437                             const struct GNUNET_DHT_PathElement *path,
    438                             struct GNUNET_TIME_Absolute exp,
    439                             const struct GNUNET_HashCode *key,
    440                             const void *data,
    441                             size_t size);
    442 
    443 
    444 /**
    445  * Start monitoring the local DHT service.
    446  *
    447  * @param handle Handle to the DHT service.
    448  * @param type Type of blocks that are of interest.
    449  * @param key Key of data of interest, NULL for all.
    450  * @param get_cb Callback to process monitored get messages.
    451  * @param get_resp_cb Callback to process monitored get response messages.
    452  * @param put_cb Callback to process monitored put messages.
    453  * @param cb_cls Closure for callbacks
    454  * @return Handle to stop monitoring.
    455  */
    456 struct GNUNET_DHT_MonitorHandle *
    457 GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle,
    458                           enum GNUNET_BLOCK_Type type,
    459                           const struct GNUNET_HashCode *key,
    460                           GNUNET_DHT_MonitorGetCB get_cb,
    461                           GNUNET_DHT_MonitorGetRespCB get_resp_cb,
    462                           GNUNET_DHT_MonitorPutCB put_cb,
    463                           void *cb_cls);
    464 
    465 
    466 /**
    467  * Stop monitoring.
    468  * On return handle will no longer be valid, caller must not use it anymore.
    469  *
    470  * @param handle The handle to the monitor request returned by
    471  *         #GNUNET_DHT_monitor_start().
    472  */
    473 void
    474 GNUNET_DHT_monitor_stop (struct GNUNET_DHT_MonitorHandle *handle);
    475 
    476 
    477 /**
    478  * Convert a peer path to a human-readable string.
    479  *
    480  * @param path array of path elements to convert to a string
    481  * @param path_len length of the @a path array
    482  * @return string representing the array of @a pids
    483  */
    484 char *
    485 GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
    486                  unsigned int path_len);
    487 
    488 
    489 /**
    490  * Verify signatures on a path consisting of @a put_path and @a get_path in
    491  * reverse order (starting at the last element of the @a get_path).  Note that
    492  * the last signature on the path is never verified as that is the slot where
    493  * our peer (@a me) would need to sign.
    494  *
    495  * @param data payload (the block)
    496  * @param data_size number of bytes in @a data
    497  * @param exp_time expiration time of @a data
    498  * @param trunc_peer peer which signature was broken or where the path was truncated,
    499  *                  NULL if path is not truncated
    500  * @param get_path array of path elements to verify
    501  * @param get_path_len length of the @a get_path array
    502  * @param put_path array of path elements to verify
    503  * @param put_path_len length of the @a put_path array
    504  * @param me our own peer identity (needed to verify the last element)
    505  * @return 0 on success, otherwise the index of
    506  *         the last path element that succeeded with verification;
    507  *         @a get_path_len + @a put_path_len if no signature was valid
    508  */
    509 unsigned int
    510 GNUNET_DHT_verify_path (const void *data,
    511                         size_t data_size,
    512                         struct GNUNET_TIME_Absolute exp_time,
    513                         const struct GNUNET_PeerIdentity *trunc_peer,
    514                         const struct GNUNET_DHT_PathElement *put_path,
    515                         unsigned int put_path_len,
    516                         const struct GNUNET_DHT_PathElement *get_path,
    517                         unsigned int get_path_len,
    518                         const struct GNUNET_PeerIdentity *me);
    519 
    520 
    521 /**
    522  * Handle to get a HELLO URL from the DHT for manual bootstrapping.
    523  */
    524 struct GNUNET_DHT_HelloGetHandle;
    525 
    526 
    527 /**
    528  * Signature called with the result of a HELLO GET operation.
    529  *
    530  * @param cls closure
    531  * @param hello_url the resulting HELLO URL, NULL on error
    532  */
    533 typedef void
    534 (*GNUNET_DHT_HelloGetCallback)(void *cls,
    535                                const char *hello_url);
    536 
    537 
    538 /**
    539  * Obtain HELLO URL of the DHT identified by @a dht_handle.
    540  *
    541  * @param dht_handle DHT to query
    542  * @param cb function to call with the result
    543  * @param cb_cls closure for @a cb
    544  * @return NULL on failure
    545  */
    546 struct GNUNET_DHT_HelloGetHandle *
    547 GNUNET_DHT_hello_get (struct GNUNET_DHT_Handle *dht_handle,
    548                       GNUNET_DHT_HelloGetCallback cb,
    549                       void *cb_cls);
    550 
    551 
    552 /**
    553  * Cancel hello get operation.
    554  *
    555  * @param[in] hgh operation to cancel.
    556  */
    557 void
    558 GNUNET_DHT_hello_get_cancel (struct GNUNET_DHT_HelloGetHandle *hgh);
    559 
    560 
    561 /**
    562  * Offer HELLO URL of the DHT identified by @a dht_handle.
    563  * Callback may be invoked once, only way to cancel is to
    564  * disconnect @a dht_handle.
    565  *
    566  * @param dht_handle DHT to query
    567  * @param url URL with a HELLO to offer to the DHT
    568  * @param cb function called when done
    569  * @param cb_cls closure for @a cb
    570  */
    571 void
    572 GNUNET_DHT_hello_offer (struct GNUNET_DHT_Handle *dht_handle,
    573                         const char *url,
    574                         GNUNET_SCHEDULER_TaskCallback cb,
    575                         void *cb_cls);
    576 
    577 
    578 #if 0                           /* keep Emacsens' auto-indent happy */
    579 {
    580 #endif
    581 #ifdef __cplusplus
    582 }
    583 #endif
    584 
    585 #endif
    586 
    587 /** @} */  /* end of group dht */
    588 
    589 /** @} */ /* end of group addition */
    590 
    591 /** @} */ /* end of group addition */