uncrustify as demanded.
[oweals/gnunet.git] / src / include / gnunet_mq_lib.h
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012-2016 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  * @author Florian Dold
23  * @author Christian Grothoff
24  *
25  * @file
26  * General-purpose message queue
27  *
28  * @defgroup mq  MQ library
29  * General-purpose message queue
30  *
31  * @see [Documentation](https://gnunet.org/message-queue-api)
32  *
33  * @{
34  */
35 #ifndef GNUNET_MQ_LIB_H
36 #define GNUNET_MQ_LIB_H
37
38 #include "gnunet_scheduler_lib.h"
39
40 /**
41  * Allocate an envelope, with extra space allocated after the space needed
42  * by the message struct.
43  * The allocated message will already have the type and size field set.
44  *
45  * @param mvar variable to store the allocated message in;
46  *             must have a header field;
47  *             can be NULL
48  * @param esize extra space to allocate after the message
49  * @param type type of the message
50  * @return the MQ message
51  */
52 #define GNUNET_MQ_msg_extra(mvar, esize, type)                \
53   GNUNET_MQ_msg_(((struct GNUNET_MessageHeader **)&(mvar)), \
54                  (esize) + sizeof *(mvar),                   \
55                  (type))
56
57 /**
58  * Allocate a GNUNET_MQ_Envelope.
59  * The contained message will already have the type and size field set.
60  *
61  * @param mvar variable to store the allocated message in;
62  *             must have a header field;
63  *             can be NULL
64  * @param type type of the message
65  * @return the allocated envelope
66  */
67 #define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra(mvar, 0, type)
68
69
70 /**
71  * Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
72  * The allocated message will already have the type and size field set.
73  *
74  * @param type type of the message
75  */
76 #define GNUNET_MQ_msg_header(type) \
77   GNUNET_MQ_msg_(NULL, sizeof(struct GNUNET_MessageHeader), type)
78
79
80 /**
81  * Allocate a GNUNET_MQ_Envelope, where the message only consists of a header and extra space.
82  * The allocated message will already have the type and size field set.
83  *
84  * @param mh pointer that will changed to point at to the allocated message header
85  * @param esize extra space to allocate after the message header
86  * @param type type of the message
87  */
88 #define GNUNET_MQ_msg_header_extra(mh, esize, type) \
89   GNUNET_MQ_msg_(&mh, (esize) + sizeof(struct GNUNET_MessageHeader), type)
90
91
92 /**
93  * Allocate a GNUNET_MQ_Envelope, and append a payload message after the given
94  * message struct.
95  *
96  * @param mvar pointer to a message struct, will be changed to point at the newly allocated message,
97  *        whose size is 'sizeof(*mvar) + ntohs (mh->size)'
98  * @param type message type of the allocated message, has no effect on the nested message
99  * @param mh message to nest
100  * @return a newly allocated 'struct GNUNET_MQ_Envelope *'
101  */
102 #define GNUNET_MQ_msg_nested_mh(mvar, type, mh)                               \
103   ({                                                                          \
104     struct GNUNET_MQ_Envelope *_ev;                                           \
105     _ev = GNUNET_MQ_msg_nested_mh_((struct GNUNET_MessageHeader **)&(mvar), \
106                                    sizeof(*(mvar)),                         \
107                                    (type),                                   \
108                                    (mh));                                    \
109     (void)(mvar)->header;  /* type check */                                   \
110     _ev;                                                                      \
111   })
112
113
114 /**
115  * Return a pointer to the message at the end of the given message.
116  *
117  * @param var pointer to a message struct, the type of the expression determines the base size,
118  *        the space after the base size is the nested message
119  * @return a 'struct GNUNET_MessageHeader *' that points at the nested message of the given message,
120  *         or NULL if the given message in @a var does not have any space after the message struct
121  */
122 #define GNUNET_MQ_extract_nested_mh(var)                               \
123   GNUNET_MQ_extract_nested_mh_((struct GNUNET_MessageHeader *)(var), \
124                                sizeof(*(var)))
125
126
127 /**
128  * Implementation of the #GNUNET_MQ_extract_nexted_mh macro.
129  *
130  * @param mh message header to extract nested message header from
131  * @param base_size size of the message before the nested message's header appears
132  * @return pointer to the nested message, does not copy the message
133  *         OR NULL in case of a malformed message.
134  */
135 const struct GNUNET_MessageHeader *
136 GNUNET_MQ_extract_nested_mh_(const struct GNUNET_MessageHeader *mh,
137                              uint16_t base_size);
138
139
140 /**
141  * Opaque handle to an envelope.
142  */
143 struct GNUNET_MQ_Envelope;
144
145
146 /**
147  * Obtain message contained in envelope.
148  *
149  * @param env the envelope
150  * @return message contained in the envelope
151  */
152 const struct GNUNET_MessageHeader *
153 GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env);
154
155
156 /**
157  * Return next envelope in queue.
158  *
159  * @param env a queued envelope
160  * @return next one, or NULL
161  */
162 const struct GNUNET_MQ_Envelope *
163 GNUNET_MQ_env_next(const struct GNUNET_MQ_Envelope *env);
164
165
166 /**
167  * Implementation of the #GNUNET_MQ_msg_nested_mh macro.
168  *
169  * @param mhp pointer to the message header pointer that will be changed to allocate at
170  *        the newly allocated space for the message.
171  * @param base_size size of the data before the nested message
172  * @param type type of the message in the envelope
173  * @param nested_mh the message to append to the message after base_size
174  */
175 struct GNUNET_MQ_Envelope *
176 GNUNET_MQ_msg_nested_mh_(struct GNUNET_MessageHeader **mhp,
177                          uint16_t base_size,
178                          uint16_t type,
179                          const struct GNUNET_MessageHeader *nested_mh);
180
181
182 /**
183  * Opaque handle to a message queue.
184  */
185 struct GNUNET_MQ_Handle;
186
187
188 /**
189  * Error codes for the queue.
190  */
191 enum GNUNET_MQ_Error {
192   /**
193    * Failed to read message from the network.
194    * FIXME: Likely not properly distinguished
195    * from TIMEOUT case in the code!
196    */
197   GNUNET_MQ_ERROR_READ = 1,
198
199   /**
200    * FIXME: document!
201    */
202   GNUNET_MQ_ERROR_WRITE = 2,
203
204   /**
205    * FIXME: document!
206    */
207   GNUNET_MQ_ERROR_TIMEOUT = 4,
208
209   /**
210    * We received a message that was malformed and thus
211    * could not be passed to its handler.
212    */
213   GNUNET_MQ_ERROR_MALFORMED = 8,
214
215   /**
216    * We received a message for which we have no matching
217    * handler.
218    */
219   GNUNET_MQ_ERROR_NO_MATCH = 16
220 };
221
222
223 /**
224  * Per envelope preferences and priorities.
225  */
226 enum GNUNET_MQ_PriorityPreferences {
227   /**
228    * Lowest priority, i.e. background traffic (i.e. NSE, FS).
229    * This is the default!
230    */
231   GNUNET_MQ_PRIO_BACKGROUND = 0,
232
233   /**
234    * Best-effort traffic (i.e. CADET relay, DHT)
235    */
236   GNUNET_MQ_PRIO_BEST_EFFORT = 1,
237
238   /**
239    * Urgent traffic (local peer, i.e. Conversation).
240    */
241   GNUNET_MQ_PRIO_URGENT = 2,
242
243   /**
244    * Highest priority, control traffic (i.e. CORE/CADET KX).
245    */
246   GNUNET_MQ_PRIO_CRITICAL_CONTROL = 3,
247
248   /**
249    * Bit mask to apply to extract the priority bits.
250    */
251   GNUNET_MQ_PRIORITY_MASK = 3,
252
253   /**
254    * Flag to indicate that unreliable delivery is acceptable.  This
255    * means TRANSPORT will not attempt to receive an
256    * acknowledgment. CORE will just pass this flag through.  CADET
257    * will use unreliable delivery if this flag is set.
258    *
259    * Note that even without this flag, messages may be lost by
260    * TRANSPORT and CORE.
261    *
262    * Thus, how "strong" the semantics of reliable delivery are depends
263    * on the layer!
264    */
265   GNUNET_MQ_PREF_UNRELIABLE = 16,
266
267   /**
268    * Flag to indicate that low latency is important.  This flag must
269    * generally not be used in combination with
270    * #GNUNET_MQ_PREF_CORKING_ALLOWED as it would be a contradiction.
271    * When this flags is set, the envelope may skip forward in the
272    * queue (depending on priority) and also TRANSPORT should attempt
273    * to pick a communicator with particularly low latency.
274    */
275   GNUNET_MQ_PREF_LOW_LATENCY = 32,
276
277   /**
278    * Flag to indicate that CORKing is acceptable. This allows the
279    * receiver to delay transmission in hope of combining this message
280    * with other messages into a larger transmission with less
281    * per-message overhead.
282    */
283   GNUNET_MQ_PREF_CORK_ALLOWED = 64,
284
285   /**
286    * Flag to indicate that high bandwidth is desired. This flag
287    * indicates that the method chosen for transmission should focus on
288    * overall goodput.  It rarely makes sense to combine this flag with
289    * #GNUNET_MQ_PREF_LOW_LATENCY.
290    */
291   GNUNET_MQ_PREF_GOODPUT = 128,
292
293   /**
294    * Flag to indicate that out-of-order delivery is OK.
295    */
296   GNUNET_MQ_PREF_OUT_OF_ORDER = 256,
297 };
298
299
300 /**
301  * Called when a message has been received.
302  *
303  * @param cls closure
304  * @param msg the received message
305  */
306 typedef void (*GNUNET_MQ_MessageCallback) (
307   void *cls,
308   const struct GNUNET_MessageHeader *msg);
309
310
311 /**
312  * Called when a message needs to be validated.
313  *
314  * @param cls closure
315  * @param msg the received message
316  * @return #GNUNET_OK if the message is well-formed,
317  *         #GNUNET_SYSERR if not
318  */
319 typedef int (*GNUNET_MQ_MessageValidationCallback) (
320   void *cls,
321   const struct GNUNET_MessageHeader *msg);
322
323
324 /**
325  * Signature of functions implementing the
326  * sending functionality of a message queue.
327  *
328  * @param mq the message queue
329  * @param msg the message to send
330  * @param impl_state state of the implementation
331  */
332 typedef void (*GNUNET_MQ_SendImpl) (struct GNUNET_MQ_Handle *mq,
333                                     const struct GNUNET_MessageHeader *msg,
334                                     void *impl_state);
335
336
337 /**
338  * Signature of functions implementing the
339  * destruction of a message queue.
340  * Implementations must not free @a mq, but should
341  * take care of @a impl_state.
342  *
343  * @param mq the message queue to destroy
344  * @param impl_state state of the implementation
345  */
346 typedef void (*GNUNET_MQ_DestroyImpl) (struct GNUNET_MQ_Handle *mq,
347                                        void *impl_state);
348
349
350 /**
351  * Implementation function that cancels the currently sent message.
352  *
353  * @param mq message queue
354  * @param impl_state state specific to the implementation
355  */
356 typedef void (*GNUNET_MQ_CancelImpl) (struct GNUNET_MQ_Handle *mq,
357                                       void *impl_state);
358
359
360 /**
361  * Generic error handler, called with the appropriate
362  * error code and the same closure specified at the creation of
363  * the message queue.
364  * Not every message queue implementation supports an error handler.
365  *
366  * @param cls closure
367  * @param error error code
368  */
369 typedef void (*GNUNET_MQ_ErrorHandler) (void *cls, enum GNUNET_MQ_Error error);
370
371
372 /**
373  * Insert @a env into the envelope DLL starting at @a env_head
374  * Note that @a env must not be in any MQ while this function
375  * is used with DLLs defined outside of the MQ module.  This
376  * is just in case some application needs to also manage a
377  * FIFO of envelopes independent of MQ itself and wants to
378  * re-use the pointers internal to @a env.  Use with caution.
379  *
380  * @param[in|out] env_head of envelope DLL
381  * @param[in|out] env_tail tail of envelope DLL
382  * @param[in|out] env element to insert at the tail
383  */
384 void
385 GNUNET_MQ_dll_insert_head(struct GNUNET_MQ_Envelope **env_head,
386                           struct GNUNET_MQ_Envelope **env_tail,
387                           struct GNUNET_MQ_Envelope *env);
388
389
390 /**
391  * Insert @a env into the envelope DLL starting at @a env_head
392  * Note that @a env must not be in any MQ while this function
393  * is used with DLLs defined outside of the MQ module.  This
394  * is just in case some application needs to also manage a
395  * FIFO of envelopes independent of MQ itself and wants to
396  * re-use the pointers internal to @a env.  Use with caution.
397  *
398  * @param[in|out] env_head of envelope DLL
399  * @param[in|out] env_tail tail of envelope DLL
400  * @param[in|out] env element to insert at the tail
401  */
402 void
403 GNUNET_MQ_dll_insert_tail(struct GNUNET_MQ_Envelope **env_head,
404                           struct GNUNET_MQ_Envelope **env_tail,
405                           struct GNUNET_MQ_Envelope *env);
406
407
408 /**
409  * Remove @a env from the envelope DLL starting at @a env_head.
410  * Note that @a env must not be in any MQ while this function
411  * is used with DLLs defined outside of the MQ module. This
412  * is just in case some application needs to also manage a
413  * FIFO of envelopes independent of MQ itself and wants to
414  * re-use the pointers internal to @a env.  Use with caution.
415  *
416  * @param[in|out] env_head of envelope DLL
417  * @param[in|out] env_tail tail of envelope DLL
418  * @param[in|out] env element to remove from the DLL
419  */
420 void
421 GNUNET_MQ_dll_remove(struct GNUNET_MQ_Envelope **env_head,
422                      struct GNUNET_MQ_Envelope **env_tail,
423                      struct GNUNET_MQ_Envelope *env);
424
425
426 /**
427  * Copy an array of handlers.
428  *
429  * Useful if the array has been delared in local memory and needs to be
430  * persisted for future use.
431  *
432  * @param handlers Array of handlers to be copied.
433  * @return A newly allocated array of handlers.
434  *         Needs to be freed with #GNUNET_free.
435  */
436 struct GNUNET_MQ_MessageHandler *
437 GNUNET_MQ_copy_handlers(const struct GNUNET_MQ_MessageHandler *handlers);
438
439
440 /**
441  * Copy an array of handlers, appending AGPL handler.
442  *
443  * Useful if the array has been delared in local memory and needs to be
444  * persisted for future use.
445  *
446  * @param handlers Array of handlers to be copied. Can be NULL (nothing done).
447  * @param agpl_handler function to call for AGPL handling
448  * @param agpl_cls closure for @a agpl_handler
449  * @return A newly allocated array of handlers.
450  *         Needs to be freed with #GNUNET_free.
451  */
452 struct GNUNET_MQ_MessageHandler *
453 GNUNET_MQ_copy_handlers2(const struct GNUNET_MQ_MessageHandler *handlers,
454                          GNUNET_MQ_MessageCallback agpl_handler,
455                          void *agpl_cls);
456
457
458 /**
459  * Count the handlers in a handler array.
460  *
461  * @param handlers Array of handlers to be counted.
462  * @return The number of handlers in the array.
463  */
464 unsigned int
465 GNUNET_MQ_count_handlers(const struct GNUNET_MQ_MessageHandler *handlers);
466
467
468 /**
469  * Message handler for a specific message type.
470  */
471 struct GNUNET_MQ_MessageHandler {
472   /**
473    * Callback to validate a message of the specified @e type.
474    * The closure given to @e mv will be this struct (not @e ctx).
475    * Using NULL means only size-validation using
476    * @e expected_size.  In this case, @e expected_size must
477    * be non-zero.
478    */
479   GNUNET_MQ_MessageValidationCallback mv;
480
481   /**
482    * Callback, called every time a new message of
483    * the specified @e type has been receied.
484    * The closure given to @e mv will be this struct (not @e ctx).
485    */
486   GNUNET_MQ_MessageCallback cb;
487
488   /**
489    * Closure for @e mv and @e cb.
490    */
491   void *cls;
492
493   /**
494    * Type of the message this handler covers, in host byte order.
495    */
496   uint16_t type;
497
498   /**
499    * Expected size of messages of this type.  Minimum size of the
500    * message if @e mv is non-NULL.  Messages of the given type will be
501    * discarded (and the connection closed with an error reported to
502    * the application) if they do not have the right size.
503    */
504   uint16_t expected_size;
505 };
506
507
508 /**
509  * End-marker for the handlers array
510  */
511 #define GNUNET_MQ_handler_end() \
512   {                             \
513     NULL, NULL, NULL, 0, 0      \
514   }
515
516
517 /**
518  * Defines a static function @a name which takes as a single argument
519  * a message handler for fixed-sized messages of type @a code and with
520  * a message type argument of @a str.  Given such an argument, the
521  * function @name will return a `struct GNUNET_MQ_MessageHandler`
522  * for the given message type.
523  *
524  * The macro is to be used as follows:
525  * <code>
526  * struct GNUNET_MessageTest { ... }; // must be fixed size
527  * static void
528  * handle_test_message (void *cls,
529  *                      const struct GNUNET_MessageTest *msg)
530  * { ... }
531  *
532  * struct GNUNET_MQ_MessageHandler handlers[] = {
533  *   GNUNET_MQ_hd_fixed_size(test_message,
534  *                           GNUNET_MESSAGE_TYPE_TEST,
535  *                           struct GNUNET_MessageTest,
536  *                           "context"),
537  *   GNUNET_MQ_handler_end()
538  * };
539  *
540  * @param name unique basename for the functions
541  * @param code message type constant
542  * @param str type of the message (a struct)
543  * @param ctx context for the callbacks
544  */
545 #define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)                   \
546   ({                                                                    \
547     void (*_cb)(void *cls, const str *msg) = &handle_ ## name;           \
548     ((struct GNUNET_MQ_MessageHandler){ NULL,                            \
549                                         (GNUNET_MQ_MessageCallback)_cb, \
550                                         (ctx),                           \
551                                         (code),                          \
552                                         sizeof(str) });                  \
553   })
554
555
556 /**
557  * Defines a static function @a name which takes two arguments and a
558  * context-pointer for validating and handling variable-sized messages
559  * of type @a code and with a message type argument of @a str.  Given
560  * such arguments, the function @name will return a `struct
561  * GNUNET_MQ_MessageHandler` for the given message type.
562  *
563  * The macro is to be used as follows:
564  * <code>
565  * struct GNUNET_MessageTest { ... }; // can be variable size
566  * static int
567  * check_test (void *cls,
568  *             const struct GNUNET_MessageTest *msg)
569  * {
570  *   const char *ctx = cls;
571  *   GNUNET_assert (0 == strcmp ("context", ctx));
572  *   // ...
573  * }
574  * static void
575  * handle_test (void *cls,
576  *              const struct GNUNET_MessageTest *msg)
577  * {
578  *   const char *ctx = cls;
579  *   GNUNET_assert (0 == strcmp ("context", ctx));
580  *   // ...
581  * }
582  *
583  * struct GNUNET_MQ_MessageHandler handlers[] = {
584  *   GNUNET_MQ_hd_var_size(test_message,
585  *                         GNUNET_MESSAGE_TYPE_TEST,
586  *                         struct GNUNET_MessageTest,
587  *                         "context"),
588  *   GNUNET_MQ_handler_end()
589  * };
590  *
591  * @param name unique basename for the functions
592  * @param code message type constant
593  * @param str type of the message (a struct)
594  * @param ctx context for the callbacks
595  */
596 #define GNUNET_MQ_hd_var_size(name, code, str, ctx)                          \
597   __extension__({                                                            \
598     int (*_mv)(void *cls, const str *msg) = &check_ ## name;                  \
599     void (*_cb)(void *cls, const str *msg) = &handle_ ## name;                \
600     ((struct GNUNET_MQ_MessageHandler){ (GNUNET_MQ_MessageValidationCallback) \
601                                         _mv,                                \
602                                         (GNUNET_MQ_MessageCallback)_cb,      \
603                                         (ctx),                                \
604                                         (code),                               \
605                                         sizeof(str) });                       \
606   })
607
608
609 /**
610  * Insert code for a "check_" function that verifies that
611  * a given variable-length message received over the network
612  * is followed by a 0-terminated string.  If the message @a m
613  * is not followed by a 0-terminated string, an error is logged
614  * and the function is returned with #GNUNET_NO.
615  *
616  * @param an IPC message with proper type to determine
617  *  the size, starting with a `struct GNUNET_MessageHeader`
618  */
619 #define GNUNET_MQ_check_zero_termination(m)                       \
620   {                                                               \
621     const char *str = (const char *)&m[1];                       \
622     const struct GNUNET_MessageHeader *hdr =                      \
623       (const struct GNUNET_MessageHeader *)m;                    \
624     uint16_t slen = ntohs(hdr->size) - sizeof(*m);              \
625     if ((0 == slen) || (memchr(str, 0, slen) != &str[slen - 1])) \
626       {                                                             \
627         GNUNET_break(0);                                           \
628         return GNUNET_NO;                                           \
629       }                                                             \
630   }
631
632
633 /**
634  * Insert code for a "check_" function that verifies that
635  * a given variable-length message received over the network
636  * is followed by another variable-length message that fits
637  * exactly with the given size.  If the message @a m
638  * is not followed by another `struct GNUNET_MessageHeader`
639  * with a size that adds up to the total size, an error is logged
640  * and the function is returned with #GNUNET_NO.
641  *
642  * @param an IPC message with proper type to determine
643  *  the size, starting with a `struct GNUNET_MessageHeader`
644  */
645 #define GNUNET_MQ_check_boxed_message(m)                 \
646   {                                                      \
647     const struct GNUNET_MessageHeader *inbox =           \
648       (const struct GNUNET_MessageHeader *)&m[1];       \
649     const struct GNUNET_MessageHeader *hdr =             \
650       (const struct GNUNET_MessageHeader *)m;           \
651     uint16_t slen = ntohs(hdr->size) - sizeof(*m);     \
652     if ((slen < sizeof(struct GNUNET_MessageHeader)) || \
653         (slen != ntohs(inbox->size)))                   \
654       {                                                    \
655         GNUNET_break(0);                                  \
656         return GNUNET_NO;                                  \
657       }                                                    \
658   }
659
660
661 /**
662  * Call the message message handler that was registered
663  * for the type of the given message in the given @a handlers list.
664  *
665  * This function is indended to be used for the implementation
666  * of message queues.
667  *
668  * @param handlers a set of handlers
669  * @param mh message to dispatch
670  * @return #GNUNET_OK on success, #GNUNET_NO if no handler matched,
671  *         #GNUNET_SYSERR if message was rejected by check function
672  */
673 int
674 GNUNET_MQ_handle_message(const struct GNUNET_MQ_MessageHandler *handlers,
675                          const struct GNUNET_MessageHeader *mh);
676
677
678 /**
679  * Create a new envelope.
680  *
681  * @param mhp message header to store the allocated message header in, can be NULL
682  * @param size size of the message to allocate
683  * @param type type of the message, will be set in the allocated message
684  * @return the allocated MQ message
685  */
686 struct GNUNET_MQ_Envelope *
687 GNUNET_MQ_msg_(struct GNUNET_MessageHeader **mhp,
688                uint16_t size,
689                uint16_t type);
690
691
692 /**
693  * Create a new envelope by copying an existing message.
694  *
695  * @param hdr header of the message to copy
696  * @return envelope containing @a hdr
697  */
698 struct GNUNET_MQ_Envelope *
699 GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr);
700
701
702 /**
703  * Discard the message queue message, free all
704  * allocated resources. Must be called in the event
705  * that a message is created but should not actually be sent.
706  *
707  * @param mqm the message to discard
708  */
709 void
710 GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm);
711
712
713 /**
714  * Function to obtain the current envelope
715  * from within #GNUNET_MQ_SendImpl implementations.
716  *
717  * @param mq message queue to interrogate
718  * @return the current envelope
719  */
720 struct GNUNET_MQ_Envelope *
721 GNUNET_MQ_get_current_envelope(struct GNUNET_MQ_Handle *mq);
722
723
724 /**
725  * Function to copy an envelope.  The envelope must not yet
726  * be in any queue or have any options or callbacks set.
727  *
728  * @param env envelope to copy
729  * @return copy of @a env
730  */
731 struct GNUNET_MQ_Envelope *
732 GNUNET_MQ_env_copy(struct GNUNET_MQ_Envelope *env);
733
734
735 /**
736  * Function to obtain the last envelope in the queue.
737  *
738  * @param mq message queue to interrogate
739  * @return the last envelope in the queue
740  */
741 struct GNUNET_MQ_Envelope *
742 GNUNET_MQ_get_last_envelope(struct GNUNET_MQ_Handle *mq);
743
744
745 /**
746  * Set application-specific options for this envelope.
747  * Overrides the options set for the queue with
748  * #GNUNET_MQ_set_options() for this message only.
749  *
750  * @param env message to set options for
751  * @param pp priority and preferences to set for @a env
752  */
753 void
754 GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env,
755                           enum GNUNET_MQ_PriorityPreferences pp);
756
757
758 /**
759  * Get performance preferences set for this envelope.
760  *
761  * @param env message to set options for
762  * @return priority and preferences to use
763  */
764 enum GNUNET_MQ_PriorityPreferences
765 GNUNET_MQ_env_get_options(struct GNUNET_MQ_Envelope *env);
766
767
768 /**
769  * Combine performance preferences set for different
770  * envelopes that are being combined into one larger envelope.
771  *
772  * @param p1 one set of preferences
773  * @param p2 second set of preferences
774  * @return combined priority and preferences to use
775  */
776 enum GNUNET_MQ_PriorityPreferences
777 GNUNET_MQ_env_combine_options(enum GNUNET_MQ_PriorityPreferences p1,
778                               enum GNUNET_MQ_PriorityPreferences p2);
779
780
781 /**
782  * Remove the first envelope that has not yet been sent from the message
783  * queue and return it.
784  *
785  * @param mq queue to remove envelope from
786  * @return NULL if queue is empty (or has no envelope that is not under transmission)
787  */
788 struct GNUNET_MQ_Envelope *
789 GNUNET_MQ_unsent_head(struct GNUNET_MQ_Handle *mq);
790
791
792 /**
793  * Set application-specific options for this queue.
794  *
795  * @param mq message queue to set options for
796  * @param pp priority and preferences to use by default
797  */
798 void
799 GNUNET_MQ_set_options(struct GNUNET_MQ_Handle *mq,
800                       enum GNUNET_MQ_PriorityPreferences pp);
801
802
803 /**
804  * Obtain the current length of the message queue.
805  *
806  * @param mq queue to inspect
807  * @return number of queued, non-transmitted messages
808  */
809 unsigned int
810 GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq);
811
812
813 /**
814  * Send a message with the given message queue.
815  * May only be called once per message.
816  *
817  * @param mq message queue
818  * @param ev the envelope with the message to send.
819  */
820 void
821 GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev);
822
823
824 /**
825  * Send a copy of a message with the given message queue.
826  * Can be called repeatedly on the same envelope.
827  *
828  * @param mq message queue
829  * @param ev the envelope with the message to send.
830  */
831 void
832 GNUNET_MQ_send_copy(struct GNUNET_MQ_Handle *mq,
833                     const struct GNUNET_MQ_Envelope *ev);
834
835
836 /**
837  * Cancel sending the message. Message must have been sent with
838  * #GNUNET_MQ_send before.  May not be called after the notify sent
839  * callback has been called
840  *
841  * @param ev queued envelope to cancel
842  */
843 void
844 GNUNET_MQ_send_cancel(struct GNUNET_MQ_Envelope *ev);
845
846
847 /**
848  * Associate the assoc_data in @a mq with a unique request id.
849  *
850  * @param mq message queue, id will be unique for the queue
851  * @param assoc_data to associate
852  */
853 uint32_t
854 GNUNET_MQ_assoc_add(struct GNUNET_MQ_Handle *mq, void *assoc_data);
855
856
857 /**
858  * Get the data associated with a @a request_id in a queue
859  *
860  * @param mq the message queue with the association
861  * @param request_id the request id we are interested in
862  * @return the associated data
863  */
864 void *
865 GNUNET_MQ_assoc_get(struct GNUNET_MQ_Handle *mq, uint32_t request_id);
866
867
868 /**
869  * Remove the association for a @a request_id
870  *
871  * @param mq the message queue with the association
872  * @param request_id the request id we want to remove
873  * @return the associated data
874  */
875 void *
876 GNUNET_MQ_assoc_remove(struct GNUNET_MQ_Handle *mq, uint32_t request_id);
877
878
879 /**
880  * Create a message queue for the specified handlers.
881  *
882  * @param send function the implements sending messages
883  * @param destroy function that implements destroying the queue
884  * @param cancel function that implements canceling a message
885  * @param impl_state for the queue, passed to @a send, @a destroy and @a cancel
886  * @param handlers array of message handlers
887  * @param error_handler handler for read and write errors
888  * @param cls closure for message handlers and error handler
889  * @return a new message queue
890  */
891 struct GNUNET_MQ_Handle *
892 GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send,
893                               GNUNET_MQ_DestroyImpl destroy,
894                               GNUNET_MQ_CancelImpl cancel,
895                               void *impl_state,
896                               const struct GNUNET_MQ_MessageHandler *handlers,
897                               GNUNET_MQ_ErrorHandler error_handler,
898                               void *cls);
899
900
901 /**
902  * Change the closure argument in all of the `handlers` of the
903  * @a mq.
904  *
905  * @param mq to modify
906  * @param handlers_cls new closure to use
907  */
908 void
909 GNUNET_MQ_set_handlers_closure(struct GNUNET_MQ_Handle *mq,
910                                void *handlers_cls);
911
912
913 /**
914  * Call a callback once the envelope has been sent, that is,
915  * sending it can not be canceled anymore.
916  * There can be only one notify sent callback per envelope.
917  *
918  * @param ev message to call the notify callback for
919  * @param cb the notify callback
920  * @param cb_cls closure for the callback
921  */
922 void
923 GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev,
924                       GNUNET_SCHEDULER_TaskCallback cb,
925                       void *cb_cls);
926
927
928 /**
929  * Destroy the message queue.
930  *
931  * @param mq message queue to destroy
932  */
933 void
934 GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq);
935
936
937 /**
938  * Handle we return for callbacks registered to be
939  * notified when #GNUNET_MQ_destroy() is called on a queue.
940  */
941 struct GNUNET_MQ_DestroyNotificationHandle;
942
943
944 /**
945  * Register function to be called whenever @a mq is being
946  * destroyed.
947  *
948  * @param mq message queue to watch
949  * @param cb function to call on @a mq destruction
950  * @param cb_cls closure for @a cb
951  * @return handle for #GNUNET_MQ_destroy_notify_cancel().
952  */
953 struct GNUNET_MQ_DestroyNotificationHandle *
954 GNUNET_MQ_destroy_notify(struct GNUNET_MQ_Handle *mq,
955                          GNUNET_SCHEDULER_TaskCallback cb,
956                          void *cb_cls);
957
958 /**
959  * Cancel registration from #GNUNET_MQ_destroy_notify().
960  *
961  * @param dnh handle for registration to cancel
962  */
963 void
964 GNUNET_MQ_destroy_notify_cancel(
965   struct GNUNET_MQ_DestroyNotificationHandle *dnh);
966
967
968 /**
969  * Call the message message handler that was registered
970  * for the type of the given message in the given message queue.
971  *
972  * This function is indended to be used for the implementation
973  * of message queues.
974  *
975  * @param mq message queue with the handlers
976  * @param mh message to dispatch
977  */
978 void
979 GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq,
980                          const struct GNUNET_MessageHeader *mh);
981
982
983 /**
984  * Call the error handler of a message queue with the given
985  * error code.  If there is no error handler, log a warning.
986  *
987  * This function is intended to be used for the implementation
988  * of message queues.
989  *
990  * @param mq message queue
991  * @param error the error type
992  */
993 void
994 GNUNET_MQ_inject_error(struct GNUNET_MQ_Handle *mq,
995                        enum GNUNET_MQ_Error error);
996
997
998 /**
999  * Call the send implementation for the next queued message, if any.
1000  * Calls the send notification for the current message unless
1001  * #GNUNET_MQ_impl_send_in_flight was called for this envelope.
1002  *
1003  * Only useful for implementing message queues, results in undefined
1004  * behavior if not used carefully.
1005  *
1006  * @param mq message queue to send the next message with
1007  */
1008 void
1009 GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq);
1010
1011
1012 /**
1013  * Call the send notification for the current message, but do not
1014  * try to send the next message until #gnunet_mq_impl_send_continue
1015  * is called.
1016  *
1017  * Only useful for implementing message queues, results in undefined
1018  * behavior if not used carefully.
1019  *
1020  * @param mq message queue to send the next message with
1021  */
1022 void
1023 GNUNET_MQ_impl_send_in_flight(struct GNUNET_MQ_Handle *mq);
1024
1025
1026 /**
1027  * Get the implementation state associated with the
1028  * message queue.
1029  *
1030  * While the GNUNET_MQ_Impl* callbacks receive the
1031  * implementation state, continuations that are scheduled
1032  * by the implementation function often only have one closure
1033  * argument, with this function it is possible to get at the
1034  * implementation state when only passing the `struct GNUNET_MQ_Handle`
1035  * as closure.
1036  *
1037  * @param mq message queue with the current message
1038  * @return message to send, never NULL
1039  */
1040 void *
1041 GNUNET_MQ_impl_state(struct GNUNET_MQ_Handle *mq);
1042
1043
1044 /**
1045  * Get the message that should currently be sent.
1046  * Fails if there is no current message.
1047  * Only useful for implementing message queues,
1048  * results in undefined behavior if not used carefully.
1049  *
1050  * @param mq message queue with the current message
1051  * @return message to send, never NULL
1052  */
1053 const struct GNUNET_MessageHeader *
1054 GNUNET_MQ_impl_current(struct GNUNET_MQ_Handle *mq);
1055
1056
1057 /**
1058  * Enum defining all known preference categories.
1059  *
1060  * @deprecated will be replaced by `enum GNUNET_MQ_PriorityPreference`
1061  */
1062 enum GNUNET_MQ_PreferenceKind {
1063   /**
1064    * No preference was expressed.
1065    */
1066   GNUNET_MQ_PREFERENCE_NONE = 0,
1067
1068   /**
1069    * The preferred transmission for this envelope focuses on
1070    * maximizing bandwidth.
1071    */
1072   GNUNET_MQ_PREFERENCE_BANDWIDTH = 1,
1073
1074   /**
1075    * The preferred transmission for this envelope foces on
1076    * minimizing latency.
1077    */
1078   GNUNET_MQ_PREFERENCE_LATENCY = 2,
1079
1080   /**
1081    * The preferred transmission for this envelope foces on
1082    * reliability.
1083    */
1084   GNUNET_MQ_PREFERENCE_RELIABILITY = 3
1085
1086 /**
1087  * Number of preference values allowed.
1088  */
1089 #define GNUNET_MQ_PREFERENCE_COUNT 4
1090 };
1091
1092
1093 /**
1094  * Convert an `enum GNUNET_MQ_PreferenceType` to a string
1095  *
1096  * @param type the preference type
1097  * @return a string or NULL if invalid
1098  *
1099  * @deprecated will be replaced by `enum GNUNET_MQ_PriorityPreference`
1100  */
1101 const char *
1102 GNUNET_MQ_preference_to_string(enum GNUNET_MQ_PreferenceKind type);
1103
1104
1105 #endif
1106
1107 /** @} */ /* end of group mq */