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 */