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