gnunet_set_service.h (16189B)
1 /* 2 This file is part of GNUnet 3 Copyright (C) 2013, 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 */ 20 21 /** 22 * @addtogroup Sets 23 * @{ 24 * 25 * @author Florian Dold 26 * @author Christian Grothoff 27 * 28 * @file 29 * Two-peer set operations 30 * 31 * @defgroup set Set service 32 * Two-peer set operations 33 * 34 * @see [Documentation](https://gnunet.org/set-subsystem) 35 * 36 * @{ 37 */ 38 39 #ifndef GNUNET_SET_SERVICE_H 40 #define GNUNET_SET_SERVICE_H 41 42 #ifdef __cplusplus 43 extern "C" 44 { 45 #if 0 /* keep Emacsens' auto-indent happy */ 46 } 47 #endif 48 #endif 49 50 51 #include "gnunet_common.h" 52 #include "gnunet_time_lib.h" 53 #include "gnunet_configuration_lib.h" 54 55 56 /** 57 * Maximum size of a context message for set operation requests. 58 */ 59 #define GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE ((1 << 16) - 1024) 60 61 62 /** 63 * Opaque handle to a set. 64 */ 65 struct GNUNET_SET_Handle; 66 67 /** 68 * Opaque handle to a set operation request from another peer. 69 */ 70 struct GNUNET_SET_Request; 71 72 /** 73 * Opaque handle to a listen operation. 74 */ 75 struct GNUNET_SET_ListenHandle; 76 77 /** 78 * Opaque handle to a set operation. 79 */ 80 struct GNUNET_SET_OperationHandle; 81 82 83 /** 84 * The operation that a set set supports. 85 */ 86 enum GNUNET_SET_OperationType 87 { 88 /** 89 * A purely local set that does not support any operation. 90 */ 91 GNUNET_SET_OPERATION_NONE, 92 93 /** 94 * Set intersection, only return elements that are in both sets. 95 */ 96 GNUNET_SET_OPERATION_INTERSECTION, 97 98 /** 99 * Set union, return all elements that are in at least one of the sets. 100 */ 101 GNUNET_SET_OPERATION_UNION 102 }; 103 104 105 /** 106 * Status for the result callback 107 */ 108 enum GNUNET_SET_Status 109 { 110 /** 111 * Everything went ok, we are transmitting an element of the 112 * result (in set, or to be removed from set, depending on 113 * the `enum GNUNET_SET_ResultMode`). 114 * 115 * Only applies to 116 * #GNUNET_SET_RESULT_FULL, 117 * #GNUNET_SET_RESULT_ADDED, 118 * #GNUNET_SET_RESULT_REMOVED, 119 */ 120 GNUNET_SET_STATUS_OK, 121 122 /** 123 * Element should be added to the result set 124 * of the local peer, i.e. the local peer is 125 * missing an element. 126 * 127 * Only applies to #GNUNET_SET_RESULT_SYMMETRIC 128 */ 129 GNUNET_SET_STATUS_ADD_LOCAL, 130 131 /** 132 * Element should be added to the result set 133 * of the remote peer, i.e. the remote peer is 134 * missing an element. 135 * 136 * Only applies to #GNUNET_SET_RESULT_SYMMETRIC 137 */ 138 GNUNET_SET_STATUS_ADD_REMOTE, 139 140 /** 141 * The other peer refused to to the operation with us, 142 * or something went wrong. 143 */ 144 GNUNET_SET_STATUS_FAILURE, 145 146 /** 147 * Success, all elements have been returned (but the other peer 148 * might still be receiving some from us, so we are not done). Only 149 * used during UNION operation. 150 */ 151 GNUNET_SET_STATUS_HALF_DONE, 152 153 /** 154 * Success, all elements have been sent (and received). 155 */ 156 GNUNET_SET_STATUS_DONE 157 }; 158 159 160 /** 161 * The way results are given to the client. 162 */ 163 enum GNUNET_SET_ResultMode 164 { 165 /** 166 * Client gets every element in the resulting set. 167 * 168 * Only supported for set intersection. 169 */ 170 GNUNET_SET_RESULT_FULL, 171 172 /** 173 * Client gets notified of the required changes 174 * for both the local and the remote set. 175 * 176 * Only supported for set 177 */ 178 GNUNET_SET_RESULT_SYMMETRIC, 179 180 /** 181 * Client gets only elements that have been removed from the set. 182 * 183 * Only supported for set intersection. 184 */ 185 GNUNET_SET_RESULT_REMOVED, 186 187 /** 188 * Client gets only elements that have been added to the set. 189 * 190 * Only supported for set union. 191 */ 192 GNUNET_SET_RESULT_ADDED 193 }; 194 195 196 /** 197 * Element stored in a set. 198 */ 199 struct GNUNET_SET_Element 200 { 201 /** 202 * Number of bytes in the buffer pointed to by data. 203 */ 204 uint16_t size; 205 206 /** 207 * Application-specific element type. 208 */ 209 uint16_t element_type; 210 211 /** 212 * Actual data of the element 213 */ 214 const void *data; 215 }; 216 217 218 /** 219 * Possible options to pass to a set operation. 220 * 221 * Used as tag for struct #GNUNET_SET_Option. 222 */ 223 enum GNUNET_SET_OptionType 224 { 225 /** 226 * List terminator. 227 */ 228 GNUNET_SET_OPTION_END=0, 229 /** 230 * Fail set operations when the other peer shows weird behavior 231 * that might by a Byzantine fault. 232 * 233 * For set union, 'v.num' is a lower bound on elements 234 * that the other peer must have in common with us. 235 */ 236 GNUNET_SET_OPTION_BYZANTINE=1, 237 /** 238 * Do not use the optimized set operation, but send full sets. 239 * Might trigger Byzantine fault detection. 240 */ 241 GNUNET_SET_OPTION_FORCE_FULL=2, 242 /** 243 * Only use optimized set operations, even though for this 244 * particular set operation they might be much slower. 245 * Might trigger Byzantine fault detection. 246 */ 247 GNUNET_SET_OPTION_FORCE_DELTA=4, 248 }; 249 250 251 /** 252 * Option for set operations. 253 */ 254 struct GNUNET_SET_Option 255 { 256 /** 257 * Type of the option. 258 */ 259 enum GNUNET_SET_OptionType type; 260 261 /** 262 * Value for the option, only used with some options. 263 */ 264 union 265 { 266 uint64_t num; 267 } v; 268 }; 269 270 271 /** 272 * Continuation used for some of the set operations 273 * 274 * @param cls closure 275 */ 276 typedef void 277 (*GNUNET_SET_Continuation) (void *cls); 278 279 280 /** 281 * Callback for set operation results. Called for each element 282 * in the result set. 283 * 284 * @param cls closure 285 * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK 286 * @param current_size current set size 287 * @param status see `enum GNUNET_SET_Status` 288 */ 289 typedef void 290 (*GNUNET_SET_ResultIterator) (void *cls, 291 const struct GNUNET_SET_Element *element, 292 uint64_t current_size, 293 enum GNUNET_SET_Status status); 294 295 /** 296 * Iterator for set elements. 297 * 298 * @param cls closure 299 * @param element the current element, NULL if all elements have been 300 * iterated over 301 * @return #GNUNET_YES to continue iterating, #GNUNET_NO to stop. 302 */ 303 typedef int 304 (*GNUNET_SET_ElementIterator) (void *cls, 305 const struct GNUNET_SET_Element *element); 306 307 308 /** 309 * Called when another peer wants to do a set operation with the 310 * local peer. If a listen error occurs, the @a request is NULL. 311 * 312 * @param cls closure 313 * @param other_peer the other peer 314 * @param context_msg message with application specific information from 315 * the other peer 316 * @param request request from the other peer (never NULL), use GNUNET_SET_accept() 317 * to accept it, otherwise the request will be refused 318 * Note that we can't just return value from the listen callback, 319 * as it is also necessary to specify the set we want to do the 320 * operation with, with sometimes can be derived from the context 321 * message. It's necessary to specify the timeout. 322 */ 323 typedef void 324 (*GNUNET_SET_ListenCallback) (void *cls, 325 const struct GNUNET_PeerIdentity *other_peer, 326 const struct GNUNET_MessageHeader *context_msg, 327 struct GNUNET_SET_Request *request); 328 329 330 typedef void 331 (*GNUNET_SET_CopyReadyCallback) (void *cls, 332 struct GNUNET_SET_Handle *copy); 333 334 335 /** 336 * Create an empty set, supporting the specified operation. 337 * 338 * @param cfg configuration to use for connecting to the 339 * set service 340 * @param op operation supported by the set 341 * Note that the operation has to be specified 342 * beforehand, as certain set operations need to maintain 343 * data structures specific to the operation 344 * @return a handle to the set 345 */ 346 struct GNUNET_SET_Handle * 347 GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg, 348 enum GNUNET_SET_OperationType op); 349 350 351 /** 352 * Add an element to the given set. 353 * After the element has been added (in the sense of being 354 * transmitted to the set service), @a cont will be called. 355 * Calls to #GNUNET_SET_add_element can be queued 356 * 357 * @param set set to add element to 358 * @param element element to add to the set 359 * @param cont continuation called after the element has been added 360 * @param cont_cls closure for @a cont 361 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the 362 * set is invalid (e.g. the set service crashed) 363 */ 364 int 365 GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, 366 const struct GNUNET_SET_Element *element, 367 GNUNET_SET_Continuation cont, 368 void *cont_cls); 369 370 371 /** 372 * Remove an element to the given set. 373 * After the element has been removed (in the sense of the request 374 * being transmitted to the set service), @a cont will be called. 375 * Multiple calls to GNUNET_SET_remove_element() can be queued 376 * 377 * @param set set to remove element from 378 * @param element element to remove from the set 379 * @param cont continuation called after the element has been removed 380 * @param cont_cls closure for @a cont 381 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the 382 * set is invalid (e.g. the set service crashed) 383 */ 384 int 385 GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, 386 const struct GNUNET_SET_Element *element, 387 GNUNET_SET_Continuation cont, 388 void *cont_cls); 389 390 391 void 392 GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set, 393 GNUNET_SET_CopyReadyCallback cb, 394 void *cls); 395 396 397 /** 398 * Destroy the set handle, and free all associated resources. 399 * Iterations must have completed (or be explicitly canceled) 400 * before destroying the corresponding set. Operations may 401 * still be pending when a set is destroyed. 402 * 403 * @param set set to destroy 404 */ 405 void 406 GNUNET_SET_destroy (struct GNUNET_SET_Handle *set); 407 408 409 /** 410 * Prepare a set operation to be evaluated with another peer. 411 * The evaluation will not start until the client provides 412 * a local set with GNUNET_SET_commit(). 413 * 414 * @param other_peer peer with the other set 415 * @param app_id hash for the application using the set 416 * @param context_msg additional information for the request 417 * @param result_mode specified how results will be returned, 418 * see `enum GNUNET_SET_ResultMode`. 419 * @param result_cb called on error or success 420 * @param result_cls closure for @a result_cb 421 * @return a handle to cancel the operation 422 */ 423 struct GNUNET_SET_OperationHandle * 424 GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, 425 const struct GNUNET_HashCode *app_id, 426 const struct GNUNET_MessageHeader *context_msg, 427 enum GNUNET_SET_ResultMode result_mode, 428 struct GNUNET_SET_Option options[], 429 GNUNET_SET_ResultIterator result_cb, 430 void *result_cls); 431 432 433 /** 434 * Wait for set operation requests for the given application ID. 435 * If the connection to the set service is lost, the listener is 436 * re-created transparently with exponential backoff. 437 * 438 * @param cfg configuration to use for connecting to 439 * the set service 440 * @param operation operation we want to listen for 441 * @param app_id id of the application that handles set operation requests 442 * @param listen_cb called for each incoming request matching the operation 443 * and application id 444 * @param listen_cls handle for @a listen_cb 445 * @return a handle that can be used to cancel the listen operation 446 */ 447 struct GNUNET_SET_ListenHandle * 448 GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg, 449 enum GNUNET_SET_OperationType op_type, 450 const struct GNUNET_HashCode *app_id, 451 GNUNET_SET_ListenCallback listen_cb, 452 void *listen_cls); 453 454 455 /** 456 * Cancel the given listen operation. After calling cancel, the 457 * listen callback for this listen handle will not be called again. 458 * Note that cancelling a listen operation will automatically reject 459 * all operations that have not yet been accepted. 460 * 461 * @param lh handle for the listen operation 462 */ 463 void 464 GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh); 465 466 467 /** 468 * Accept a request we got via GNUNET_SET_listen(). Must be called during 469 * GNUNET_SET_listen(), as the `struct GNUNET_SET_Request` becomes invalid 470 * afterwards. 471 * Call GNUNET_SET_commit() to provide the local set to use for the operation, 472 * and to begin the exchange with the remote peer. 473 * 474 * @param request request to accept 475 * @param result_mode specified how results will be returned, 476 * see `enum GNUNET_SET_ResultMode`. 477 * @param result_cb callback for the results 478 * @param result_cls closure for @a result_cb 479 * @return a handle to cancel the operation 480 */ 481 struct GNUNET_SET_OperationHandle * 482 GNUNET_SET_accept (struct GNUNET_SET_Request *request, 483 enum GNUNET_SET_ResultMode result_mode, 484 struct GNUNET_SET_Option options[], 485 GNUNET_SET_ResultIterator result_cb, 486 void *result_cls); 487 488 489 /** 490 * Commit a set to be used with a set operation. 491 * This function is called once we have fully constructed 492 * the set that we want to use for the operation. At this 493 * time, the P2P protocol can then begin to exchange the 494 * set information and call the result callback with the 495 * result information. 496 * 497 * @param oh handle to the set operation 498 * @param set the set to use for the operation 499 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the 500 * set is invalid (e.g. the set service crashed) 501 */ 502 int 503 GNUNET_SET_commit (struct GNUNET_SET_OperationHandle *oh, 504 struct GNUNET_SET_Handle *set); 505 506 507 /** 508 * Cancel the given set operation. May not be called after the 509 * operation's `GNUNET_SET_ResultIterator` has been called with a 510 * status that indicates error, timeout or done. 511 * 512 * @param oh set operation to cancel 513 */ 514 void 515 GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh); 516 517 518 /** 519 * Iterate over all elements in the given set. 520 * Note that this operation involves transferring every element of the set 521 * from the service to the client, and is thus costly. 522 * Only one iteration per set may be active at the same time. 523 * 524 * @param set the set to iterate over 525 * @param iter the iterator to call for each element 526 * @param iter_cls closure for @a iter 527 * @return #GNUNET_YES if the iteration started successfully, 528 * #GNUNET_NO if another iteration was still active, 529 * #GNUNET_SYSERR if the set is invalid (e.g. the server crashed, disconnected) 530 */ 531 int 532 GNUNET_SET_iterate (struct GNUNET_SET_Handle *set, 533 GNUNET_SET_ElementIterator iter, 534 void *iter_cls); 535 536 537 /** 538 * Stop iteration over all elements in the given set. Can only 539 * be called before the iteration has "naturally" completed its 540 * turn. 541 * 542 * @param set the set to stop iterating over 543 */ 544 void 545 GNUNET_SET_iterate_cancel (struct GNUNET_SET_Handle *set); 546 547 548 /** 549 * Create a copy of an element. The copy 550 * must be GNUNET_free-d by the caller. 551 * 552 * @param element the element to copy 553 * @return the copied element 554 */ 555 struct GNUNET_SET_Element * 556 GNUNET_SET_element_dup (const struct GNUNET_SET_Element *element); 557 558 559 /** 560 * Hash a set element. 561 * 562 * @param element the element that should be hashed 563 * @param[out] ret_hash a pointer to where the hash of @a element 564 * should be stored 565 */ 566 void 567 GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, 568 struct GNUNET_HashCode *ret_hash); 569 570 571 #if 0 /* keep Emacsens' auto-indent happy */ 572 { 573 #endif 574 #ifdef __cplusplus 575 } 576 #endif 577 578 #endif 579 580 /** @} */ /* end of group */ 581 582 /** @} */ /* end of group addition */