gnunet_setu_service.h (11748B)
1 /* 2 This file is part of GNUnet 3 Copyright (C) 2013, 2014, 2020 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 * @addtogroup Sets 22 * @{ 23 * 24 * @author Florian Dold 25 * @author Christian Grothoff 26 * 27 * @file 28 * Two-peer set union operations 29 * 30 * @defgroup set Set union service 31 * Two-peer set operations 32 * 33 * @{ 34 */ 35 36 #ifndef GNUNET_SETU_SERVICE_H 37 #define GNUNET_SETU_SERVICE_H 38 39 #ifdef __cplusplus 40 extern "C" 41 { 42 #if 0 /* keep Emacsens' auto-indent happy */ 43 } 44 #endif 45 #endif 46 47 48 #include "gnunet_common.h" 49 #include "gnunet_time_lib.h" 50 #include "gnunet_configuration_lib.h" 51 52 53 /** 54 * Maximum size of a context message for set operation requests. 55 */ 56 #define GNUNET_SETU_CONTEXT_MESSAGE_MAX_SIZE ((1 << 16) - 1024) 57 58 /** 59 * Opaque handle to a set. 60 */ 61 struct GNUNET_SETU_Handle; 62 63 /** 64 * Opaque handle to a set operation request from another peer. 65 */ 66 struct GNUNET_SETU_Request; 67 68 /** 69 * Opaque handle to a listen operation. 70 */ 71 struct GNUNET_SETU_ListenHandle; 72 73 /** 74 * Opaque handle to a set operation. 75 */ 76 struct GNUNET_SETU_OperationHandle; 77 78 79 /** 80 * Status for the result callback 81 */ 82 enum GNUNET_SETU_Status 83 { 84 85 /** 86 * Element should be added to the result set of the local peer, i.e. the 87 * local peer is missing an element. 88 */ 89 GNUNET_SETU_STATUS_ADD_LOCAL, 90 91 /** 92 * Element should be added to the result set of the remote peer, i.e. the 93 * remote peer is missing an element. Only used if 94 * #GNUNET_SETU_OPTION_SYMMETRIC is set. 95 */ 96 GNUNET_SETU_STATUS_ADD_REMOTE, 97 98 /** 99 * The other peer refused to do the operation with us, or something went 100 * wrong. 101 */ 102 GNUNET_SETU_STATUS_FAILURE, 103 104 /** 105 * Success, all elements have been sent (and received). 106 */ 107 GNUNET_SETU_STATUS_DONE 108 }; 109 110 111 /** 112 * Element stored in a set. 113 */ 114 struct GNUNET_SETU_Element 115 { 116 /** 117 * Number of bytes in the buffer pointed to by data. 118 */ 119 uint16_t size; 120 121 /** 122 * Application-specific element type. 123 */ 124 uint16_t element_type; 125 126 /** 127 * Actual data of the element 128 */ 129 const void *data; 130 }; 131 132 133 /** 134 * Possible options to pass to a set operation. 135 * 136 * Used as tag for struct #GNUNET_SETU_Option. 137 */ 138 enum GNUNET_SETU_OptionType 139 { 140 /** 141 * List terminator. 142 */ 143 GNUNET_SETU_OPTION_END=0, 144 145 /** 146 * Fail set operations when the other peer shows weird behavior 147 * that might by a Byzantine fault. 148 * 149 * For set union, 'v.num' is a lower bound on elements that the other peer 150 * must have in common with us. 151 */ 152 GNUNET_SETU_OPTION_BYZANTINE=1, 153 154 /** 155 * Do not use the optimized set operation, but send full sets. Might 156 * trigger Byzantine fault detection. 157 */ 158 GNUNET_SETU_OPTION_FORCE_FULL=2, 159 160 /** 161 * Only use optimized set operations, even though for this particular set 162 * operation they might be much slower. Might trigger Byzantine fault 163 * detection. 164 */ 165 GNUNET_SETU_OPTION_FORCE_DELTA=4, 166 167 /** 168 * Notify client also if we are sending a value to the other peer. 169 */ 170 GNUNET_SETU_OPTION_SYMMETRIC = 8, 171 172 /** 173 * Byzantine upper bound. Is the maximal plausible number of elements 174 * a peer can have default max uint64 175 */ 176 GNUNET_SETU_OPTION_CUSTOM_BYZANTINE_UPPER_BOUND = 16, 177 178 /** 179 * Bandwidth latency tradeoff determines how much bytes a single RTT is 180 * worth, which is a performance setting 181 */ 182 GNUNET_SETU_OPTION_CUSTOM_BANDWIDTH_LATENCY_TRADEOFF= 32, 183 184 /** 185 * The factor determines the number of buckets an IBF has which is 186 * multiplied by the estimated setsize default: 2 187 */ 188 GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKET_NUMBER_FACTOR= 64, 189 190 /** 191 * This setting determines to how many IBF buckets an single elements 192 * is mapped to. 193 */ 194 GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKETS_PER_ELEMENT= 128 195 }; 196 197 198 /** 199 * Option for set operations. 200 */ 201 struct GNUNET_SETU_Option 202 { 203 /** 204 * Type of the option. 205 */ 206 enum GNUNET_SETU_OptionType type; 207 208 /** 209 * Value for the option, only used with some options. 210 */ 211 union 212 { 213 uint64_t num; 214 } v; 215 }; 216 217 218 /** 219 * Callback for set union operation results. Called for each element 220 * in the result set. 221 * 222 * @param cls closure 223 * @param element a result element, only valid if status is #GNUNET_SETU_STATUS_OK 224 * @param current_size current set size 225 * @param status see `enum GNUNET_SETU_Status` 226 */ 227 typedef void 228 (*GNUNET_SETU_ResultIterator) (void *cls, 229 const struct GNUNET_SETU_Element *element, 230 uint64_t current_size, 231 enum GNUNET_SETU_Status status); 232 233 234 /** 235 * Called when another peer wants to do a set operation with the 236 * local peer. If a listen error occurs, the @a request is NULL. 237 * 238 * @param cls closure 239 * @param other_peer the other peer 240 * @param context_msg message with application specific information from 241 * the other peer 242 * @param request request from the other peer (never NULL), use GNUNET_SETU_accept() 243 * to accept it, otherwise the request will be refused 244 * Note that we can't just return value from the listen callback, 245 * as it is also necessary to specify the set we want to do the 246 * operation with, with sometimes can be derived from the context 247 * message. It's necessary to specify the timeout. 248 */ 249 typedef void 250 (*GNUNET_SETU_ListenCallback) (void *cls, 251 const struct GNUNET_PeerIdentity *other_peer, 252 const struct GNUNET_MessageHeader *context_msg, 253 struct GNUNET_SETU_Request *request); 254 255 256 /** 257 * Create an empty set, supporting the specified operation. 258 * 259 * @param cfg configuration to use for connecting to the 260 * set service 261 * @return a handle to the set 262 */ 263 struct GNUNET_SETU_Handle * 264 GNUNET_SETU_create (const struct GNUNET_CONFIGURATION_Handle *cfg); 265 266 267 /** 268 * Add an element to the given set. 269 * 270 * @param set set to add element to 271 * @param element element to add to the set 272 * @param cb function to call when finished, can be NULL 273 * @param cb_cls closure for @a cb 274 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the 275 * set is invalid (e.g. the set service crashed) 276 */ 277 int 278 GNUNET_SETU_add_element (struct GNUNET_SETU_Handle *set, 279 const struct GNUNET_SETU_Element *element, 280 GNUNET_SCHEDULER_TaskCallback cb, 281 void *cb_cls); 282 283 284 /** 285 * Destroy the set handle, and free all associated resources. Operations may 286 * still be pending when a set is destroyed (and will be allowed to complete). 287 * 288 * @param set set to destroy 289 */ 290 void 291 GNUNET_SETU_destroy (struct GNUNET_SETU_Handle *set); 292 293 294 /** 295 * Prepare a set operation to be evaluated with another peer. 296 * The evaluation will not start until the client provides a 297 * local set with GNUNET_SETU_commit(). 298 * 299 * @param other_peer peer with the other set 300 * @param app_id hash for the application using the set 301 * @param context_msg additional information for the request 302 * @param options options to use when processing the request 303 * @param result_cb called on error or success 304 * @param result_cls closure for @a result_cb 305 * @return a handle to cancel the operation 306 */ 307 struct GNUNET_SETU_OperationHandle * 308 GNUNET_SETU_prepare (const struct GNUNET_PeerIdentity *other_peer, 309 const struct GNUNET_HashCode *app_id, 310 const struct GNUNET_MessageHeader *context_msg, 311 const struct GNUNET_SETU_Option options[], 312 GNUNET_SETU_ResultIterator result_cb, 313 void *result_cls); 314 315 316 /** 317 * Wait for set operation requests for the given application ID. 318 * If the connection to the set service is lost, the listener is 319 * re-created transparently with exponential backoff. 320 * 321 * @param cfg configuration to use for connecting to 322 * the set service 323 * @param app_id id of the application that handles set operation requests 324 * @param listen_cb called for each incoming request matching the operation 325 * and application id 326 * @param listen_cls handle for @a listen_cb 327 * @return a handle that can be used to cancel the listen operation 328 */ 329 struct GNUNET_SETU_ListenHandle * 330 GNUNET_SETU_listen (const struct GNUNET_CONFIGURATION_Handle *cfg, 331 const struct GNUNET_HashCode *app_id, 332 GNUNET_SETU_ListenCallback listen_cb, 333 void *listen_cls); 334 335 336 /** 337 * Cancel the given listen operation. After calling cancel, the 338 * listen callback for this listen handle will not be called again. 339 * Note that cancelling a listen operation will automatically reject 340 * all operations that have not yet been accepted. 341 * 342 * @param lh handle for the listen operation 343 */ 344 void 345 GNUNET_SETU_listen_cancel (struct GNUNET_SETU_ListenHandle *lh); 346 347 348 /** 349 * Accept a request we got via GNUNET_SETU_listen(). Must be called during 350 * GNUNET_SETU_listen(), as the `struct GNUNET_SETU_Request` becomes invalid 351 * afterwards. 352 * Call GNUNET_SETU_commit() to provide the local set to use for the operation, 353 * and to begin the exchange with the remote peer. 354 * 355 * @param request request to accept 356 * @param options options to use when processing the request 357 * @param result_cb callback for the results 358 * @param result_cls closure for @a result_cb 359 * @return a handle to cancel the operation 360 */ 361 struct GNUNET_SETU_OperationHandle * 362 GNUNET_SETU_accept (struct GNUNET_SETU_Request *request, 363 const struct GNUNET_SETU_Option options[], 364 GNUNET_SETU_ResultIterator result_cb, 365 void *result_cls); 366 367 368 /** 369 * Commit a set to be used with a set operation. 370 * This function is called once we have fully constructed 371 * the set that we want to use for the operation. At this 372 * time, the P2P protocol can then begin to exchange the 373 * set information and call the result callback with the 374 * result information. 375 * 376 * @param oh handle to the set operation 377 * @param set the set to use for the operation 378 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the 379 * set is invalid (e.g. the set service crashed) 380 */ 381 int 382 GNUNET_SETU_commit (struct GNUNET_SETU_OperationHandle *oh, 383 struct GNUNET_SETU_Handle *set); 384 385 386 /** 387 * Cancel the given set operation. May not be called after the operation's 388 * `GNUNET_SETU_ResultIterator` has been called with a status of 389 * #GNUNET_SETU_STATUS_FAILURE or #GNUNET_SETU_STATUS_DONE. 390 * 391 * @param oh set operation to cancel 392 */ 393 void 394 GNUNET_SETU_operation_cancel (struct GNUNET_SETU_OperationHandle *oh); 395 396 397 /** 398 * Hash a set element. 399 * 400 * @param element the element that should be hashed 401 * @param[out] ret_hash a pointer to where the hash of @a element 402 * should be stored 403 */ 404 void 405 GNUNET_SETU_element_hash (const struct GNUNET_SETU_Element *element, 406 struct GNUNET_HashCode *ret_hash); 407 408 409 #if 0 /* keep Emacsens' auto-indent happy */ 410 { 411 #endif 412 #ifdef __cplusplus 413 } 414 #endif 415 416 #endif 417 418 /** @} */ /* end of group */ 419 420 /** @} */ /* end of group addition */