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