This file is part of GNUnet.
Copyright (C) 2012-2016 GNUnet e.V.
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
*
* @{
*/
-#ifndef GNUNET_MQ_H
-#define GNUNET_MQ_H
+#ifndef GNUNET_MQ_LIB_H
+#define GNUNET_MQ_LIB_H
+#include "gnunet_scheduler_lib.h"
/**
* Allocate an envelope, with extra space allocated after the space needed
* The allocated message will already have the type and size field set.
*
* @param mvar variable to store the allocated message in;
- * must have a header field
+ * must have a header field;
+ * can be NULL
* @param esize extra space to allocate after the message
* @param type type of the message
* @return the MQ message
*/
-#define GNUNET_MQ_msg_extra(mvar, esize, type) GNUNET_MQ_msg_(((struct GNUNET_MessageHeader**) &(mvar)), (esize) + sizeof *(mvar), (type))
+#define GNUNET_MQ_msg_extra(mvar, esize, type) \
+ GNUNET_MQ_msg_ (((struct GNUNET_MessageHeader **) &(mvar)), \
+ (esize) + sizeof *(mvar), \
+ (type))
/**
* Allocate a GNUNET_MQ_Envelope.
* The contained message will already have the type and size field set.
*
* @param mvar variable to store the allocated message in;
- * must have a header field
+ * must have a header field;
+ * can be NULL
* @param type type of the message
* @return the allocated envelope
*/
-#define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra(mvar, 0, type)
+#define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra (mvar, 0, type)
/**
*
* @param type type of the message
*/
-#define GNUNET_MQ_msg_header(type) GNUNET_MQ_msg_ (NULL, sizeof (struct GNUNET_MessageHeader), type)
+#define GNUNET_MQ_msg_header(type) \
+ GNUNET_MQ_msg_ (NULL, sizeof (struct GNUNET_MessageHeader), type)
/**
* @param esize extra space to allocate after the message header
* @param type type of the message
*/
-#define GNUNET_MQ_msg_header_extra(mh, esize, type) GNUNET_MQ_msg_ (&mh, (esize) + sizeof (struct GNUNET_MessageHeader), type)
+#define GNUNET_MQ_msg_header_extra(mh, esize, type) \
+ GNUNET_MQ_msg_ (&mh, (esize) + sizeof (struct GNUNET_MessageHeader), type)
/**
* @param mh message to nest
* @return a newly allocated 'struct GNUNET_MQ_Envelope *'
*/
-#define GNUNET_MQ_msg_nested_mh(mvar, type, mh) GNUNET_MQ_msg_nested_mh_((((void)(mvar)->header), (struct GNUNET_MessageHeader**) &(mvar)), sizeof (*(mvar)), (type), mh)
+#define GNUNET_MQ_msg_nested_mh(mvar, type, mh) \
+ ({ \
+ struct GNUNET_MQ_Envelope *_ev; \
+ _ev = GNUNET_MQ_msg_nested_mh_ ((struct GNUNET_MessageHeader **) &(mvar), \
+ sizeof (*(mvar)), \
+ (type), \
+ (mh)); \
+ (void) (mvar)->header; /* type check */ \
+ _ev; \
+ })
/**
* @return a 'struct GNUNET_MessageHeader *' that points at the nested message of the given message,
* or NULL if the given message in @a var does not have any space after the message struct
*/
-#define GNUNET_MQ_extract_nested_mh(var) GNUNET_MQ_extract_nested_mh_ ((struct GNUNET_MessageHeader *) (var), sizeof (*(var)))
+#define GNUNET_MQ_extract_nested_mh(var) \
+ GNUNET_MQ_extract_nested_mh_ ((struct GNUNET_MessageHeader *) (var), \
+ sizeof (*(var)))
/**
* @param mh message header to extract nested message header from
* @param base_size size of the message before the nested message's header appears
* @return pointer to the nested message, does not copy the message
+ * OR NULL in case of a malformed message.
*/
const struct GNUNET_MessageHeader *
GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh,
struct GNUNET_MQ_Envelope;
+/**
+ * Obtain message contained in envelope.
+ *
+ * @param env the envelope
+ * @return message contained in the envelope
+ */
+const struct GNUNET_MessageHeader *
+GNUNET_MQ_env_get_msg (const struct GNUNET_MQ_Envelope *env);
+
+
+/**
+ * Return next envelope in queue.
+ *
+ * @param env a queued envelope
+ * @return next one, or NULL
+ */
+const struct GNUNET_MQ_Envelope *
+GNUNET_MQ_env_next (const struct GNUNET_MQ_Envelope *env);
+
+
/**
* Implementation of the #GNUNET_MQ_msg_nested_mh macro.
*
};
+/**
+ * Per envelope preferences and priorities.
+ */
+enum GNUNET_MQ_PriorityPreferences
+{
+
+ /**
+ * Lowest priority, i.e. background traffic (i.e. NSE, FS).
+ * This is the default!
+ */
+ GNUNET_MQ_PRIO_BACKGROUND = 0,
+
+ /**
+ * Best-effort traffic (i.e. CADET relay, DHT)
+ */
+ GNUNET_MQ_PRIO_BEST_EFFORT = 1,
+
+ /**
+ * Urgent traffic (local peer, i.e. Conversation).
+ */
+ GNUNET_MQ_PRIO_URGENT = 2,
+
+ /**
+ * Highest priority, control traffic (i.e. CORE/CADET KX).
+ */
+ GNUNET_MQ_PRIO_CRITICAL_CONTROL = 3,
+
+ /**
+ * Bit mask to apply to extract the priority bits.
+ */
+ GNUNET_MQ_PRIORITY_MASK = 3,
+
+ /**
+ * Flag to indicate that unreliable delivery is acceptable. This
+ * means TRANSPORT will not attempt to receive an
+ * acknowledgment. CORE will just pass this flag through. CADET
+ * will use unreliable delivery if this flag is set.
+ *
+ * Note that even without this flag, messages may be lost by
+ * TRANSPORT and CORE.
+ *
+ * Thus, how "strong" the semantics of reliable delivery are depends
+ * on the layer!
+ */
+ GNUNET_MQ_PREF_UNRELIABLE = 16,
+
+ /**
+ * Flag to indicate that low latency is important. This flag must
+ * generally not be used in combination with
+ * #GNUNET_MQ_PREF_CORKING_ALLOWED as it would be a contradiction.
+ * When this flags is set, the envelope may skip forward in the
+ * queue (depending on priority) and also TRANSPORT should attempt
+ * to pick a communicator with particularly low latency.
+ */
+ GNUNET_MQ_PREF_LOW_LATENCY = 32,
+
+ /**
+ * Flag to indicate that CORKing is acceptable. This allows the
+ * receiver to delay transmission in hope of combining this message
+ * with other messages into a larger transmission with less
+ * per-message overhead.
+ */
+ GNUNET_MQ_PREF_CORK_ALLOWED = 64,
+
+ /**
+ * Flag to indicate that high bandwidth is desired. This flag
+ * indicates that the method chosen for transmission should focus on
+ * overall goodput. It rarely makes sense to combine this flag with
+ * #GNUNET_MQ_PREF_LOW_LATENCY.
+ */
+ GNUNET_MQ_PREF_GOODPUT = 128,
+
+ /**
+ * Flag to indicate that out-of-order delivery is OK.
+ */
+ GNUNET_MQ_PREF_OUT_OF_ORDER = 256,
+
+ /**
+ * Flag to indicate no buffering.
+ */
+ GNUNET_MQ_PREF_NO_BUFFER = 512,
+
+ /**
+ * Flag to indicate default
+ */
+ GNUNET_MQ_PREF_DEFAULT = 1024,
+
+ /**
+ * Flag to indicate reliable
+ */
+ GNUNET_MQ_PREF_RELIABLE = 2048
+
+};
+
+
/**
* Called when a message has been received.
*
* @param cls closure
* @param msg the received message
*/
-typedef void
-(*GNUNET_MQ_MessageCallback) (void *cls,
- const struct GNUNET_MessageHeader *msg);
+typedef void (*GNUNET_MQ_MessageCallback) (
+ void *cls,
+ const struct GNUNET_MessageHeader *msg);
/**
* @return #GNUNET_OK if the message is well-formed,
* #GNUNET_SYSERR if not
*/
-typedef int
-(*GNUNET_MQ_MessageValidationCallback) (void *cls,
- const struct GNUNET_MessageHeader *msg);
+typedef int (*GNUNET_MQ_MessageValidationCallback) (
+ void *cls,
+ const struct GNUNET_MessageHeader *msg);
/**
* @param msg the message to send
* @param impl_state state of the implementation
*/
-typedef void
-(*GNUNET_MQ_SendImpl) (struct GNUNET_MQ_Handle *mq,
- const struct GNUNET_MessageHeader *msg,
- void *impl_state);
+typedef void (*GNUNET_MQ_SendImpl) (struct GNUNET_MQ_Handle *mq,
+ const struct GNUNET_MessageHeader *msg,
+ void *impl_state);
/**
* @param mq the message queue to destroy
* @param impl_state state of the implementation
*/
-typedef void
-(*GNUNET_MQ_DestroyImpl) (struct GNUNET_MQ_Handle *mq,
- void *impl_state);
+typedef void (*GNUNET_MQ_DestroyImpl) (struct GNUNET_MQ_Handle *mq,
+ void *impl_state);
/**
* @param mq message queue
* @param impl_state state specific to the implementation
*/
-typedef void
-(*GNUNET_MQ_CancelImpl) (struct GNUNET_MQ_Handle *mq,
- void *impl_state);
-
-
-/**
- * Callback used for notifications
- *
- * @param cls closure
- */
-typedef void
-(*GNUNET_MQ_NotifyCallback) (void *cls);
+typedef void (*GNUNET_MQ_CancelImpl) (struct GNUNET_MQ_Handle *mq,
+ void *impl_state);
/**
* @param cls closure
* @param error error code
*/
-typedef void
-(*GNUNET_MQ_ErrorHandler) (void *cls,
- enum GNUNET_MQ_Error error);
+typedef void (*GNUNET_MQ_ErrorHandler) (void *cls, enum GNUNET_MQ_Error error);
+
+
+/**
+ * Insert @a env into the envelope DLL starting at @a env_head
+ * Note that @a env must not be in any MQ while this function
+ * is used with DLLs defined outside of the MQ module. This
+ * is just in case some application needs to also manage a
+ * FIFO of envelopes independent of MQ itself and wants to
+ * re-use the pointers internal to @a env. Use with caution.
+ *
+ * @param[in|out] env_head of envelope DLL
+ * @param[in|out] env_tail tail of envelope DLL
+ * @param[in|out] env element to insert at the tail
+ */
+void
+GNUNET_MQ_dll_insert_tail (struct GNUNET_MQ_Envelope **env_head,
+ struct GNUNET_MQ_Envelope **env_tail,
+ struct GNUNET_MQ_Envelope *env);
+
+
+/**
+ * Remove @a env from the envelope DLL starting at @a env_head.
+ * Note that @a env must not be in any MQ while this function
+ * is used with DLLs defined outside of the MQ module. This
+ * is just in case some application needs to also manage a
+ * FIFO of envelopes independent of MQ itself and wants to
+ * re-use the pointers internal to @a env. Use with caution.
+ *
+ * @param[in|out] env_head of envelope DLL
+ * @param[in|out] env_tail tail of envelope DLL
+ * @param[in|out] env element to remove from the DLL
+ */
+void
+GNUNET_MQ_dll_remove (struct GNUNET_MQ_Envelope **env_head,
+ struct GNUNET_MQ_Envelope **env_tail,
+ struct GNUNET_MQ_Envelope *env);
+
+
+/**
+ * Copy an array of handlers.
+ *
+ * Useful if the array has been delared in local memory and needs to be
+ * persisted for future use.
+ *
+ * @param handlers Array of handlers to be copied.
+ * @return A newly allocated array of handlers.
+ * Needs to be freed with #GNUNET_free.
+ */
+struct GNUNET_MQ_MessageHandler *
+GNUNET_MQ_copy_handlers (const struct GNUNET_MQ_MessageHandler *handlers);
+
+
+/**
+ * Copy an array of handlers, appending AGPL handler.
+ *
+ * Useful if the array has been delared in local memory and needs to be
+ * persisted for future use.
+ *
+ * @param handlers Array of handlers to be copied. Can be NULL (nothing done).
+ * @param agpl_handler function to call for AGPL handling
+ * @param agpl_cls closure for @a agpl_handler
+ * @return A newly allocated array of handlers.
+ * Needs to be freed with #GNUNET_free.
+ */
+struct GNUNET_MQ_MessageHandler *
+GNUNET_MQ_copy_handlers2 (const struct GNUNET_MQ_MessageHandler *handlers,
+ GNUNET_MQ_MessageCallback agpl_handler,
+ void *agpl_cls);
+
+
+/**
+ * Count the handlers in a handler array.
+ *
+ * @param handlers Array of handlers to be counted.
+ * @return The number of handlers in the array.
+ */
+unsigned int
+GNUNET_MQ_count_handlers (const struct GNUNET_MQ_MessageHandler *handlers);
/**
/**
* End-marker for the handlers array
*/
-#define GNUNET_MQ_handler_end() { NULL, NULL, NULL, 0, 0 }
+#define GNUNET_MQ_handler_end() \
+ { \
+ NULL, NULL, NULL, 0, 0 \
+ }
/**
* @param str type of the message (a struct)
* @param ctx context for the callbacks
*/
-#define GNUNET_MQ_hd_fixed_size(name,code,str,ctx) \
- ({ \
- void (*_cb)(void *cls, const str *msg) = &handle_##name; \
- ((struct GNUNET_MQ_MessageHandler) { \
- NULL, (GNUNET_MQ_MessageCallback) _cb, \
- (ctx), (code), sizeof (str) }); \
+#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx) \
+ ({ \
+ void (*_cb) (void *cls, const str *msg) = &handle_##name; \
+ ((struct GNUNET_MQ_MessageHandler){NULL, \
+ (GNUNET_MQ_MessageCallback) _cb, \
+ (ctx), \
+ (code), \
+ sizeof (str)}); \
})
* @param str type of the message (a struct)
* @param ctx context for the callbacks
*/
-#define GNUNET_MQ_hd_var_size(name,code,str,ctx) \
- ({ \
- int (*_mv)(void *cls, const str *msg) = &check_##name; \
- void (*_cb)(void *cls, const str *msg) = &handle_##name; \
- ((struct GNUNET_MQ_MessageHandler) \
- { (GNUNET_MQ_MessageValidationCallback) _mv, \
- (GNUNET_MQ_MessageCallback) _cb, \
- (ctx), (code), sizeof (str) }); \
+#define GNUNET_MQ_hd_var_size(name, code, str, ctx) \
+ __extension__({ \
+ int (*_mv) (void *cls, const str *msg) = &check_##name; \
+ void (*_cb) (void *cls, const str *msg) = &handle_##name; \
+ ((struct GNUNET_MQ_MessageHandler){(GNUNET_MQ_MessageValidationCallback) \
+ _mv, \
+ (GNUNET_MQ_MessageCallback) _cb, \
+ (ctx), \
+ (code), \
+ sizeof (str)}); \
})
+/**
+ * Insert code for a "check_" function that verifies that
+ * a given variable-length message received over the network
+ * is followed by a 0-terminated string. If the message @a m
+ * is not followed by a 0-terminated string, an error is logged
+ * and the function is returned with #GNUNET_NO.
+ *
+ * @param an IPC message with proper type to determine
+ * the size, starting with a `struct GNUNET_MessageHeader`
+ */
+#define GNUNET_MQ_check_zero_termination(m) \
+ { \
+ const char *str = (const char *) &m[1]; \
+ const struct GNUNET_MessageHeader *hdr = \
+ (const struct GNUNET_MessageHeader *) m; \
+ uint16_t slen = ntohs (hdr->size) - sizeof (*m); \
+ if ((0 == slen) || (memchr (str, 0, slen) != &str[slen - 1])) \
+ { \
+ GNUNET_break (0); \
+ return GNUNET_NO; \
+ } \
+ }
+
+
+/**
+ * Insert code for a "check_" function that verifies that
+ * a given variable-length message received over the network
+ * is followed by another variable-length message that fits
+ * exactly with the given size. If the message @a m
+ * is not followed by another `struct GNUNET_MessageHeader`
+ * with a size that adds up to the total size, an error is logged
+ * and the function is returned with #GNUNET_NO.
+ *
+ * @param an IPC message with proper type to determine
+ * the size, starting with a `struct GNUNET_MessageHeader`
+ */
+#define GNUNET_MQ_check_boxed_message(m) \
+ { \
+ const struct GNUNET_MessageHeader *inbox = \
+ (const struct GNUNET_MessageHeader *) &m[1]; \
+ const struct GNUNET_MessageHeader *hdr = \
+ (const struct GNUNET_MessageHeader *) m; \
+ uint16_t slen = ntohs (hdr->size) - sizeof (*m); \
+ if ((slen < sizeof (struct GNUNET_MessageHeader)) || \
+ (slen != ntohs (inbox->size))) \
+ { \
+ GNUNET_break (0); \
+ return GNUNET_NO; \
+ } \
+ }
+
+
+/**
+ * Call the message message handler that was registered
+ * for the type of the given message in the given @a handlers list.
+ *
+ * This function is indended to be used for the implementation
+ * of message queues.
+ *
+ * @param handlers a set of handlers
+ * @param mh message to dispatch
+ * @return #GNUNET_OK on success, #GNUNET_NO if no handler matched,
+ * #GNUNET_SYSERR if message was rejected by check function
+ */
+int
+GNUNET_MQ_handle_message (const struct GNUNET_MQ_MessageHandler *handlers,
+ const struct GNUNET_MessageHeader *mh);
+
+
/**
* Create a new envelope.
*
GNUNET_MQ_get_current_envelope (struct GNUNET_MQ_Handle *mq);
+/**
+ * Function to copy an envelope. The envelope must not yet
+ * be in any queue or have any options or callbacks set.
+ *
+ * @param env envelope to copy
+ * @return copy of @a env
+ */
+struct GNUNET_MQ_Envelope *
+GNUNET_MQ_env_copy (struct GNUNET_MQ_Envelope *env);
+
+
/**
* Function to obtain the last envelope in the queue.
*
* #GNUNET_MQ_set_options() for this message only.
*
* @param env message to set options for
- * @param flags flags to use (meaning is queue-specific)
- * @param extra additional buffer for further data (also queue-specific)
+ * @param pp priority and preferences to set for @a env
*/
void
GNUNET_MQ_env_set_options (struct GNUNET_MQ_Envelope *env,
- uint64_t flags,
- const void *extra);
+ enum GNUNET_MQ_PriorityPreferences pp);
/**
- * Get application-specific options for this envelope.
+ * Get performance preferences set for this envelope.
*
* @param env message to set options for
- * @param[out] flags set to flags to use (meaning is queue-specific)
- * @return extra additional buffer for further data (also queue-specific)
+ * @return priority and preferences to use
*/
-const void *
-GNUNET_MQ_env_get_options (struct GNUNET_MQ_Envelope *env,
- uint64_t *flags);
+enum GNUNET_MQ_PriorityPreferences
+GNUNET_MQ_env_get_options (struct GNUNET_MQ_Envelope *env);
+
+
+/**
+ * Combine performance preferences set for different
+ * envelopes that are being combined into one larger envelope.
+ *
+ * @param p1 one set of preferences
+ * @param p2 second set of preferences
+ * @return combined priority and preferences to use
+ */
+enum GNUNET_MQ_PriorityPreferences
+GNUNET_MQ_env_combine_options (enum GNUNET_MQ_PriorityPreferences p1,
+ enum GNUNET_MQ_PriorityPreferences p2);
+
+
+/**
+ * Remove the first envelope that has not yet been sent from the message
+ * queue and return it.
+ *
+ * @param mq queue to remove envelope from
+ * @return NULL if queue is empty (or has no envelope that is not under transmission)
+ */
+struct GNUNET_MQ_Envelope *
+GNUNET_MQ_unsent_head (struct GNUNET_MQ_Handle *mq);
/**
* Set application-specific options for this queue.
*
* @param mq message queue to set options for
- * @param flags flags to use (meaning is queue-specific)
- * @param extra additional buffer for further data (also queue-specific)
+ * @param pp priority and preferences to use by default
*/
void
GNUNET_MQ_set_options (struct GNUNET_MQ_Handle *mq,
- uint64_t flags,
- const void *extra);
+ enum GNUNET_MQ_PriorityPreferences pp);
/**
* @param ev the envelope with the message to send.
*/
void
-GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq,
- struct GNUNET_MQ_Envelope *ev);
+GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev);
/**
* @param assoc_data to associate
*/
uint32_t
-GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq,
- void *assoc_data);
+GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq, void *assoc_data);
/**
* @return the associated data
*/
void *
-GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq,
- uint32_t request_id);
+GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq, uint32_t request_id);
/**
* @return the associated data
*/
void *
-GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq,
- uint32_t request_id);
+GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq, uint32_t request_id);
/**
*
* @param ev message to call the notify callback for
* @param cb the notify callback
- * @param cls closure for the callback
+ * @param cb_cls closure for the callback
*/
void
GNUNET_MQ_notify_sent (struct GNUNET_MQ_Envelope *ev,
- GNUNET_MQ_NotifyCallback cb,
- void *cls);
+ GNUNET_SCHEDULER_TaskCallback cb,
+ void *cb_cls);
/**
GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq);
+/**
+ * Handle we return for callbacks registered to be
+ * notified when #GNUNET_MQ_destroy() is called on a queue.
+ */
+struct GNUNET_MQ_DestroyNotificationHandle;
+
+
+/**
+ * Register function to be called whenever @a mq is being
+ * destroyed.
+ *
+ * @param mq message queue to watch
+ * @param cb function to call on @a mq destruction
+ * @param cb_cls closure for @a cb
+ * @return handle for #GNUNET_MQ_destroy_notify_cancel().
+ */
+struct GNUNET_MQ_DestroyNotificationHandle *
+GNUNET_MQ_destroy_notify (struct GNUNET_MQ_Handle *mq,
+ GNUNET_SCHEDULER_TaskCallback cb,
+ void *cb_cls);
+
+/**
+ * Cancel registration from #GNUNET_MQ_destroy_notify().
+ *
+ * @param dnh handle for registration to cancel
+ */
+void
+GNUNET_MQ_destroy_notify_cancel (
+ struct GNUNET_MQ_DestroyNotificationHandle *dnh);
+
+
/**
* Call the message message handler that was registered
* for the type of the given message in the given message queue.
/**
* Call the send implementation for the next queued message, if any.
+ * Calls the send notification for the current message unless
+ * #GNUNET_MQ_impl_send_in_flight was called for this envelope.
+ *
* Only useful for implementing message queues, results in undefined
* behavior if not used carefully.
*
/**
- * Get the message that should currently be sent. The returned
- * message is only valid until #GNUNET_MQ_impl_send_continue is
- * called. Fails if there is no current message. Only useful for
- * implementing message queues, results in undefined behavior if not
- * used carefully.
+ * Call the send notification for the current message, but do not
+ * try to send the next message until #gnunet_mq_impl_send_continue
+ * is called.
*
- * @param mq message queue with the current message, only valid
- * until #GNUNET_MQ_impl_send_continue() is called
- * @return message to send, never NULL
+ * Only useful for implementing message queues, results in undefined
+ * behavior if not used carefully.
+ *
+ * @param mq message queue to send the next message with
*/
-const struct GNUNET_MessageHeader *
-GNUNET_MQ_impl_current (struct GNUNET_MQ_Handle *mq);
+void
+GNUNET_MQ_impl_send_in_flight (struct GNUNET_MQ_Handle *mq);
/**
GNUNET_MQ_impl_state (struct GNUNET_MQ_Handle *mq);
+/**
+ * Get the message that should currently be sent.
+ * Fails if there is no current message.
+ * Only useful for implementing message queues,
+ * results in undefined behavior if not used carefully.
+ *
+ * @param mq message queue with the current message
+ * @return message to send, never NULL
+ */
+const struct GNUNET_MessageHeader *
+GNUNET_MQ_impl_current (struct GNUNET_MQ_Handle *mq);
+
+
+/**
+ * Enum defining all known preference categories.
+ *
+ * @deprecated will be replaced by `enum GNUNET_MQ_PriorityPreference`
+ */
+enum GNUNET_MQ_PreferenceKind
+{
+
+ /**
+ * No preference was expressed.
+ */
+ GNUNET_MQ_PREFERENCE_NONE = 0,
+
+ /**
+ * The preferred transmission for this envelope focuses on
+ * maximizing bandwidth.
+ */
+ GNUNET_MQ_PREFERENCE_BANDWIDTH = 1,
+
+ /**
+ * The preferred transmission for this envelope foces on
+ * minimizing latency.
+ */
+ GNUNET_MQ_PREFERENCE_LATENCY = 2,
+
+ /**
+ * The preferred transmission for this envelope foces on
+ * reliability.
+ */
+ GNUNET_MQ_PREFERENCE_RELIABILITY = 3
+
+/**
+ * Number of preference values allowed.
+ */
+#define GNUNET_MQ_PREFERENCE_COUNT 4
+
+};
+
+
+/**
+ * Convert an `enum GNUNET_MQ_PreferenceType` to a string
+ *
+ * @param type the preference type
+ * @return a string or NULL if invalid
+ *
+ * @deprecated will be replaced by `enum GNUNET_MQ_PriorityPreference`
+ */
+const char *
+GNUNET_MQ_preference_to_string (enum GNUNET_MQ_PreferenceKind type);
+
+
#endif
/** @} */ /* end of group mq */