aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ats/ats_api_scheduling.c35
-rw-r--r--src/conversation/conversation_api.c88
-rw-r--r--src/include/gnunet_client_lib.h59
-rw-r--r--src/include/gnunet_mq_lib.h235
-rw-r--r--src/include/gnunet_server_lib.h10
-rw-r--r--src/set/set_api.c195
-rw-r--r--src/util/mq.c107
-rw-r--r--src/util/perf_crypto_asymmetric.c2
8 files changed, 468 insertions, 263 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 0d0d102db4..bc730b2486 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -357,16 +357,14 @@ release_session (struct GNUNET_ATS_SchedulingHandle *sh,
* message from the service.
*
* @param cls the `struct GNUNET_ATS_SchedulingHandle`
- * @param msg message received, NULL on timeout or fatal error
+ * @param srm message received
*/
static void
-process_ats_session_release_message (void *cls,
- const struct GNUNET_MessageHeader *msg)
+handle_ats_session_release (void *cls,
+ const struct GNUNET_ATS_SessionReleaseMessage *srm)
{
struct GNUNET_ATS_SchedulingHandle *sh = cls;
- const struct GNUNET_ATS_SessionReleaseMessage *srm;
- srm = (const struct GNUNET_ATS_SessionReleaseMessage *) msg;
/* Note: peer field in srm not necessary right now,
but might be good to have in the future */
release_session (sh,
@@ -379,18 +377,16 @@ process_ats_session_release_message (void *cls,
* message from the service.
*
* @param cls the `struct GNUNET_ATS_SchedulingHandle`
- * @param msg message received, NULL on timeout or fatal error
+ * @param m message received
*/
static void
-process_ats_address_suggestion_message (void *cls,
- const struct GNUNET_MessageHeader *msg)
+handle_ats_address_suggestion (void *cls,
+ const struct AddressSuggestionMessage *m)
{
struct GNUNET_ATS_SchedulingHandle *sh = cls;
- const struct AddressSuggestionMessage *m;
struct GNUNET_ATS_AddressRecord *ar;
uint32_t session_id;
- m = (const struct AddressSuggestionMessage *) msg;
session_id = ntohl (m->session_id);
if (0 == session_id)
{
@@ -528,14 +524,17 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh,
static void
reconnect (struct GNUNET_ATS_SchedulingHandle *sh)
{
- static const struct GNUNET_MQ_MessageHandler handlers[] =
- { { &process_ats_session_release_message,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE,
- sizeof (struct GNUNET_ATS_SessionReleaseMessage) },
- { &process_ats_address_suggestion_message,
- GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION,
- sizeof (struct AddressSuggestionMessage) },
- { NULL, 0, 0 } };
+ GNUNET_MQ_hd_fixed_size (ats_session_release,
+ GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE,
+ struct GNUNET_ATS_SessionReleaseMessage);
+ GNUNET_MQ_hd_fixed_size (ats_address_suggestion,
+ GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION,
+ struct AddressSuggestionMessage);
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ make_ats_session_release_handler (sh),
+ make_ats_address_suggestion_handler (sh),
+ GNUNET_MQ_handler_end ()
+ };
struct GNUNET_MQ_Envelope *ev;
struct ClientStartMessage *init;
unsigned int i;
diff --git a/src/conversation/conversation_api.c b/src/conversation/conversation_api.c
index f28e71a98a..a9dc1f27f3 100644
--- a/src/conversation/conversation_api.c
+++ b/src/conversation/conversation_api.c
@@ -252,17 +252,15 @@ transmit_phone_audio (void *cls,
* We received a `struct ClientPhoneRingMessage`
*
* @param cls the `struct GNUNET_CONVERSATION_Phone`
- * @param msg the message
+ * @param ring the message
*/
static void
handle_phone_ring (void *cls,
- const struct GNUNET_MessageHeader *msg)
+ const struct ClientPhoneRingMessage *ring)
{
struct GNUNET_CONVERSATION_Phone *phone = cls;
- const struct ClientPhoneRingMessage *ring;
struct GNUNET_CONVERSATION_Caller *caller;
- ring = (const struct ClientPhoneRingMessage *) msg;
switch (phone->state)
{
case PS_REGISTER:
@@ -294,13 +292,11 @@ handle_phone_ring (void *cls,
*/
static void
handle_phone_hangup (void *cls,
- const struct GNUNET_MessageHeader *msg)
+ const struct ClientPhoneHangupMessage *hang)
{
struct GNUNET_CONVERSATION_Phone *phone = cls;
- const struct ClientPhoneHangupMessage *hang;
struct GNUNET_CONVERSATION_Caller *caller;
- hang = (const struct ClientPhoneHangupMessage *) msg;
for (caller = phone->caller_head; NULL != caller; caller = caller->next)
if (hang->cid == caller->cid)
break;
@@ -351,17 +347,15 @@ handle_phone_hangup (void *cls,
* We received a `struct ClientPhoneSuspendMessage`.
*
* @param cls the `struct GNUNET_CONVERSATION_Phone`
- * @param msg the message
+ * @param suspend the message
*/
static void
handle_phone_suspend (void *cls,
- const struct GNUNET_MessageHeader *msg)
+ const struct ClientPhoneSuspendMessage *suspend)
{
struct GNUNET_CONVERSATION_Phone *phone = cls;
struct GNUNET_CONVERSATION_Caller *caller;
- const struct ClientPhoneSuspendMessage *suspend;
- suspend = (const struct ClientPhoneSuspendMessage *) msg;
for (caller = phone->caller_head; NULL != caller; caller = caller->next)
if (suspend->cid == caller->cid)
break;
@@ -396,17 +390,15 @@ handle_phone_suspend (void *cls,
* We received a `struct ClientPhoneResumeMessage`.
*
* @param cls the `struct GNUNET_CONVERSATION_Phone`
- * @param msg the message
+ * @param resume the message
*/
static void
handle_phone_resume (void *cls,
- const struct GNUNET_MessageHeader *msg)
+ const struct ClientPhoneResumeMessage *resume)
{
struct GNUNET_CONVERSATION_Phone *phone = cls;
struct GNUNET_CONVERSATION_Caller *caller;
- const struct ClientPhoneResumeMessage *resume;
- resume = (const struct ClientPhoneResumeMessage *) msg;
for (caller = phone->caller_head; NULL != caller; caller = caller->next)
if (resume->cid == caller->cid)
break;
@@ -440,20 +432,34 @@ handle_phone_resume (void *cls,
/**
+ * We received a `struct ClientAudioMessage`, check it is well-formed.
+ *
+ * @param cls the `struct GNUNET_CONVERSATION_Phone`
+ * @param am the message
+ * @return #GNUNET_OK if @a am is well-formed
+ */
+static int
+check_phone_audio (void *cls,
+ const struct ClientAudioMessage *am)
+{
+ /* any variable-size payload is OK */
+ return GNUNET_OK;
+}
+
+
+/**
* We received a `struct ClientAudioMessage`
*
* @param cls the `struct GNUNET_CONVERSATION_Phone`
- * @param msg the message
+ * @param am the message
*/
static void
-handle_phone_audio_message (void *cls,
- const struct GNUNET_MessageHeader *msg)
+handle_phone_audio (void *cls,
+ const struct ClientAudioMessage *am)
{
struct GNUNET_CONVERSATION_Phone *phone = cls;
- const struct ClientAudioMessage *am;
struct GNUNET_CONVERSATION_Caller *caller;
- am = (const struct ClientAudioMessage *) msg;
for (caller = phone->caller_head; NULL != caller; caller = caller->next)
if (am->cid == caller->cid)
break;
@@ -466,7 +472,7 @@ handle_phone_audio_message (void *cls,
break;
case CS_ACTIVE:
caller->speaker->play (caller->speaker->cls,
- ntohs (msg->size) - sizeof (struct ClientAudioMessage),
+ ntohs (am->header.size) - sizeof (struct ClientAudioMessage),
&am[1]);
break;
case CS_CALLEE_SUSPENDED:
@@ -531,24 +537,28 @@ clean_up_callers (struct GNUNET_CONVERSATION_Phone *phone)
static void
reconnect_phone (struct GNUNET_CONVERSATION_Phone *phone)
{
- static struct GNUNET_MQ_MessageHandler handlers[] =
- {
- { &handle_phone_ring,
- GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING,
- sizeof (struct ClientPhoneRingMessage) },
- { &handle_phone_hangup,
- GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP,
- sizeof (struct ClientPhoneHangupMessage) },
- { &handle_phone_suspend,
- GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND,
- sizeof (struct ClientPhoneSuspendMessage) },
- { &handle_phone_resume,
- GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME,
- sizeof (struct ClientPhoneResumeMessage) },
- { &handle_phone_audio_message,
- GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO,
- 0 },
- { NULL, 0, 0 }
+ GNUNET_MQ_hd_fixed_size (phone_ring,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING,
+ struct ClientPhoneRingMessage);
+ GNUNET_MQ_hd_fixed_size (phone_hangup,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP,
+ struct ClientPhoneHangupMessage);
+ GNUNET_MQ_hd_fixed_size (phone_suspend,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND,
+ struct ClientPhoneSuspendMessage);
+ GNUNET_MQ_hd_fixed_size (phone_resume,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME,
+ struct ClientPhoneResumeMessage);
+ GNUNET_MQ_hd_var_size (phone_audio,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO,
+ struct ClientAudioMessage);
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ make_phone_ring_handler (phone),
+ make_phone_hangup_handler (phone),
+ make_phone_suspend_handler (phone),
+ make_phone_resume_handler (phone),
+ make_phone_audio_handler (phone),
+ GNUNET_MQ_handler_end ()
};
struct GNUNET_MQ_Envelope *e;
struct ClientPhoneRegisterMessage *reg;
diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h
index 93c2a3f9ce..4bac4d5f36 100644
--- a/src/include/gnunet_client_lib.h
+++ b/src/include/gnunet_client_lib.h
@@ -43,18 +43,57 @@ extern "C"
#endif
#endif
+#include "gnunet_mq_lib.h"
/**
* Opaque handle for a connection to a service.
*/
struct GNUNET_CLIENT_Connection;
+
+/**
+ * Create a message queue to connect to a GNUnet service.
+ * If handlers are specfied, receive messages from the connection.
+ *
+ * @param connection the client connection
+ * @param handlers handlers for receiving messages, can be NULL
+ * @param error_handler error handler
+ * @param error_handler_cls closure for the @a error_handler
+ * @return the message queue
+ */
+struct GNUNET_MQ_Handle *
+GNUNET_CLIENT_connect2 (const char *service_name,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_MQ_MessageHandler *handlers,
+ GNUNET_MQ_ErrorHandler error_handler,
+ void *error_handler_cls);
+
+
+/**
+ * Create a message queue for a GNUNET_CLIENT_Connection.
+ * If handlers are specfied, receive messages from the connection.
+ *
+ * @param connection the client connection
+ * @param handlers handlers for receiving messages
+ * @param error_handler error handler
+ * @param error_handler_cls closure for the @a error_handler
+ * @return the message queue
+ * @deprecated use #GNUNET_CLIENT_connect2
+ */
+struct GNUNET_MQ_Handle *
+GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
+ const struct GNUNET_MQ_MessageHandler *handlers,
+ GNUNET_MQ_ErrorHandler error_handler,
+ void *error_handler_cls);
+
+
/**
* Get a connection with a service.
*
* @param service_name name of the service
* @param cfg configuration to use
* @return NULL on error (service unknown to configuration)
+ * @deprecated use #GNUNET_CLIENT_connect2
*/
struct GNUNET_CLIENT_Connection *
GNUNET_CLIENT_connect (const char *service_name,
@@ -73,6 +112,7 @@ GNUNET_CLIENT_connect (const char *service_name,
* which case the message may still be lost).
*
* @param client handle to the service connection
+ * @deprecated
*/
void
GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client);
@@ -85,8 +125,9 @@ GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client);
* @param cls closure
* @param msg message received, NULL on timeout or fatal error
*/
-typedef void (*GNUNET_CLIENT_MessageHandler) (void *cls,
- const struct GNUNET_MessageHeader *msg);
+typedef void
+(*GNUNET_CLIENT_MessageHandler) (void *cls,
+ const struct GNUNET_MessageHeader *msg);
/**
@@ -96,10 +137,12 @@ typedef void (*GNUNET_CLIENT_MessageHandler) (void *cls,
* @param handler function to call with the message
* @param handler_cls closure for @a handler
* @param timeout how long to wait until timing out
+ * @deprecated
*/
void
GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *client,
- GNUNET_CLIENT_MessageHandler handler, void *handler_cls,
+ GNUNET_CLIENT_MessageHandler handler,
+ void *handler_cls,
struct GNUNET_TIME_Relative timeout);
@@ -128,6 +171,7 @@ struct GNUNET_CLIENT_TransmitHandle;
* @return NULL if someone else is already waiting to be notified
* non-NULL if the notify callback was queued (can be used to cancel
* using #GNUNET_CONNECTION_notify_transmit_ready_cancel)
+ * @deprecated
*/
struct GNUNET_CLIENT_TransmitHandle *
GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client,
@@ -142,6 +186,7 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client,
* Cancel a request for notification.
*
* @param th handle from the original request.
+ * @deprecated
*/
void
GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle
@@ -168,6 +213,7 @@ GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle
* @param rn_cls closure for @a rn
* @return #GNUNET_OK on success, #GNUNET_SYSERR if a request
* is already pending
+ * @deprecated
*/
int
GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *client,
@@ -191,8 +237,9 @@ struct GNUNET_CLIENT_TestHandle;
* #GNUNET_NO if the service is not running
* #GNUNET_SYSERR if the configuration is invalid
*/
-typedef void (*GNUNET_CLIENT_TestResultCallback)(void *cls,
- int result);
+typedef void
+(*GNUNET_CLIENT_TestResultCallback)(void *cls,
+ int result);
/**
@@ -207,6 +254,7 @@ typedef void (*GNUNET_CLIENT_TestResultCallback)(void *cls,
* @param cb function to call with the result
* @param cb_cls closure for @a cb
* @return handle to cancel the test
+ * @deprecated
*/
struct GNUNET_CLIENT_TestHandle *
GNUNET_CLIENT_service_test (const char *service,
@@ -219,6 +267,7 @@ GNUNET_CLIENT_service_test (const char *service,
* Abort testing for service.
*
* @param th test handle
+ * @deprecated
*/
void
GNUNET_CLIENT_service_test_cancel (struct GNUNET_CLIENT_TestHandle *th);
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h
index 971c87b18d..38ebf6b17c 100644
--- a/src/include/gnunet_mq_lib.h
+++ b/src/include/gnunet_mq_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2012-2013 GNUnet e.V.
+ 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
@@ -20,6 +20,7 @@
/**
* @author Florian Dold
+ * @author Christian Grothoff
*
* @file
* General-purpose message queue
@@ -117,7 +118,7 @@ GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh,
/**
- * Implementation of the GNUNET_MQ_msg_nested_mh macro.
+ * Implementation of the #GNUNET_MQ_msg_nested_mh macro.
*
* @param mhp pointer to the message header pointer that will be changed to allocate at
* the newly allocated space for the message.
@@ -132,13 +133,6 @@ GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp,
const struct GNUNET_MessageHeader *nested_mh);
-
-/**
- * End-marker for the handlers array
- */
-#define GNUNET_MQ_HANDLERS_END {NULL, 0, 0}
-
-
/**
* Opaque handle to a message queue.
*/
@@ -156,7 +150,9 @@ struct GNUNET_MQ_Envelope;
enum GNUNET_MQ_Error
{
/**
- * FIXME: document!
+ * Failed to read message from the network.
+ * FIXME: Likely not properly distinguished
+ * from TIMEOUT case in the code!
*/
GNUNET_MQ_ERROR_READ = 1,
@@ -168,7 +164,13 @@ enum GNUNET_MQ_Error
/**
* FIXME: document!
*/
- GNUNET_MQ_ERROR_TIMEOUT = 4
+ GNUNET_MQ_ERROR_TIMEOUT = 4,
+
+ /**
+ * We received a message that was malformed and thus
+ * could not be passed to its handler.
+ */
+ GNUNET_MQ_ERROR_MALFORMED = 8
};
@@ -184,6 +186,19 @@ typedef void
/**
+ * Called when a message needs to be validated.
+ *
+ * @param cls closure
+ * @param msg the received message
+ * @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);
+
+
+/**
* Signature of functions implementing the
* sending functionality of a message queue.
*
@@ -251,26 +266,136 @@ typedef void
struct GNUNET_MQ_MessageHandler
{
/**
+ * Callback to validate a message of the specified @e type.
+ * The closure given to @e mv will be this struct (not @e ctx).
+ * Using NULL means only size-validation using
+ * @e expected_size. In this case, @e expected_size must
+ * be non-zero.
+ */
+ GNUNET_MQ_MessageValidationCallback mv;
+
+ /**
* Callback, called every time a new message of
- * the specified type has been receied.
+ * the specified @e type has been receied.
+ * The closure given to @e mv will be this struct (not @e ctx).
*/
GNUNET_MQ_MessageCallback cb;
/**
- * Type of the message this handler covers.
+ * Closure for @e mv and @e cb.
+ */
+ void *cls;
+
+ /**
+ * Type of the message this handler covers, in host byte order.
*/
uint16_t type;
/**
- * Expected size of messages of this type. Use 0 for
- * variable-size. If non-zero, messages of the given
- * type will be discarded (and the connection closed)
- * if they do not have the right size.
+ * Expected size of messages of this type. Minimum size of the
+ * message if @e mv is non-NULL. Messages of the given type will be
+ * discarded (and the connection closed with an error reported to
+ * the application) if they do not have the right size.
*/
uint16_t expected_size;
};
+/**
+ * End-marker for the handlers array
+ */
+#define GNUNET_MQ_handler_end() {NULL, NULL, NULL, 0, 0}
+
+
+/**
+ * Defines a static function @a name which takes as a single argument
+ * a message handler for fixed-sized messages of type @a code and with
+ * a message type argument of @a str. Given such an argument, the
+ * function @name will return a `struct GNUNET_MQ_MessageHandler`
+ * for the given message type.
+ *
+ * The macro is to be used as follows:
+ * <code>
+ * struct GNUNET_MessageTest { ... }; // must be fixed size
+ * GNUNET_MQ_hd_fixed_size(test_message,
+ * GNUNET_MESSAGE_TYPE_TEST,
+ * struct GNUNET_MessageTest);
+ * static void
+ * handle_test_message (void *cls, // the struct GNUNET_MQ_MessageHandler
+ * const struct GNUNET_MessageTest *msg)
+ * { ... }
+ *
+ * struct GNUNET_MQ_MessageHandler handlers[] = {
+ * make_test_message_handler (),
+ * GNUNET_MQ_handler_end()
+ * };
+ *
+ * @param name unique basename for the functions
+ * @param code message type constant
+ * @param str type of the message (a struct)
+ */
+#define GNUNET_MQ_hd_fixed_size(name,code,str) \
+ struct GNUNET_MQ_MessageHandler \
+ make_##name##_handler (void *cls) { \
+ void (*cb)(void *cls, const str *msg) = &handle_##name; \
+ struct GNUNET_MQ_MessageHandler mh = { \
+ NULL, (GNUNET_MQ_MessageCallback) cb, \
+ cls, code, sizeof (str) }; \
+ return mh; \
+ }
+
+
+/**
+ * Defines a static function @a name which takes two arguments and a
+ * context-pointer for validating and handling variable-sized messages
+ * of type @a code and with a message type argument of @a str. Given
+ * such arguments, the function @name will return a `struct
+ * GNUNET_MQ_MessageHandler` for the given message type.
+ *
+ * The macro is to be used as follows:
+ * <code>
+ * struct GNUNET_MessageTest { ... }; // can be variable size
+ * GNUNET_MQ_hd_var_size(test_message,
+ * GNUNET_MESSAGE_TYPE_TEST,
+ * struct GNUNET_MessageTest);
+ * static int
+ * check_test (void *cls,
+ * const struct GNUNET_MessageTest *msg)
+ * {
+ * const char *ctx = cls;
+ * GNUNET_assert (0 == strcmp ("context", ctx));
+ * // ...
+ * }
+ * static void
+ * handle_test (void *cls,
+ * const struct GNUNET_MessageTest *msg)
+ * {
+ * const char *ctx = cls;
+ * GNUNET_assert (0 == strcmp ("context", ctx));
+ * // ...
+ * }
+ *
+ * struct GNUNET_MQ_MessageHandler handlers[] = {
+ * make_test_message_handler ("context"),
+ * GNUNET_MQ_handler_end()
+ * };
+ *
+ * @param name unique basename for the functions
+ * @param code message type constant
+ * @param str type of the message (a struct)
+ */
+#define GNUNET_MQ_hd_var_size(name,code,str) \
+ struct GNUNET_MQ_MessageHandler \
+ make_##name##_handler (void *ctx) { \
+ int (*mv)(void *cls, const str *msg) = &check_##name; \
+ void (*cb)(void *cls, const str *msg) = &handle_##name;\
+ struct GNUNET_MQ_MessageHandler mh = \
+ { (GNUNET_MQ_MessageValidationCallback) mv, \
+ (GNUNET_MQ_MessageCallback) cb, \
+ ctx, code, sizeof (str) }; \
+ return mh; \
+ }
+
/**
* Create a new envelope.
@@ -321,17 +446,18 @@ GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev);
/**
- * Associate the assoc_data in mq with a unique request id.
+ * Associate the assoc_data in @a mq with a unique request id.
*
* @param mq message queue, id will be unique for the queue
* @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);
/**
- * Get the data associated with a request id in a queue
+ * Get the data associated with a @a request_id in a queue
*
* @param mq the message queue with the association
* @param request_id the request id we are interested in
@@ -343,7 +469,7 @@ GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq,
/**
- * Remove the association for a request id
+ * Remove the association for a @a request_id
*
* @param mq the message queue with the association
* @param request_id the request id we want to remove
@@ -355,33 +481,6 @@ GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq,
/**
- * Create a message queue for a GNUNET_CLIENT_Connection.
- * If handlers are specfied, receive messages from the connection.
- *
- * @param connection the client connection
- * @param handlers handlers for receiving messages
- * @param error_handler error handler
- * @param cls closure for the handlers
- * @return the message queue
- */
-struct GNUNET_MQ_Handle *
-GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
- const struct GNUNET_MQ_MessageHandler *handlers,
- GNUNET_MQ_ErrorHandler error_handler,
- void *cls);
-
-
-/**
- * Create a message queue for a GNUNET_SERVER_Client.
- *
- * @param client the client
- * @return the message queue
- */
-struct GNUNET_MQ_Handle *
-GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
-
-
-/**
* Create a message queue for the specified handlers.
*
* @param send function the implements sending messages
@@ -404,24 +503,6 @@ GNUNET_MQ_queue_for_callbacks (GNUNET_MQ_SendImpl send,
/**
- * Replace the handlers of a message queue with new handlers. Takes
- * effect immediately, even for messages that already have been
- * received, but for with the handler has not been called.
- *
- * If the message queue does not support receiving messages,
- * this function has no effect.
- *
- * @param mq message queue
- * @param new_handlers new handlers
- * @param cls new closure for the handlers
- */
-void
-GNUNET_MQ_replace_handlers (struct GNUNET_MQ_Handle *mq,
- const struct GNUNET_MQ_MessageHandler *new_handlers,
- void *cls);
-
-
-/**
* Call a callback once the envelope has been sent, that is,
* sending it can not be canceled anymore.
* There can be only one notify sent callback per envelope.
@@ -476,10 +557,9 @@ GNUNET_MQ_inject_error (struct GNUNET_MQ_Handle *mq,
/**
- * Call the send implementation for the next queued message,
- * if any.
- * Only useful for implementing message queues,
- * results in undefined behavior if not used carefully.
+ * Call the send implementation for the next queued message, if any.
+ * Only useful for implementing message queues, results in undefined
+ * behavior if not used carefully.
*
* @param mq message queue to send the next message with
*/
@@ -488,15 +568,14 @@ GNUNET_MQ_impl_send_continue (struct GNUNET_MQ_Handle *mq);
/**
- * 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.
+ * 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.
*
* @param mq message queue with the current message, only valid
- * until #GNUNET_MQ_impl_send_continue is called
+ * until #GNUNET_MQ_impl_send_continue() is called
* @return message to send, never NULL
*/
const struct GNUNET_MessageHeader *
@@ -511,7 +590,7 @@ GNUNET_MQ_impl_current (struct GNUNET_MQ_Handle *mq);
* implementation state, continuations that are scheduled
* by the implementation function often only have one closure
* argument, with this function it is possible to get at the
- * implementation state when only passing the GNUNET_MQ_Handle
+ * implementation state when only passing the `struct GNUNET_MQ_Handle`
* as closure.
*
* @param mq message queue with the current message
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
index 1ad2fc8b77..0ea9a18eba 100644
--- a/src/include/gnunet_server_lib.h
+++ b/src/include/gnunet_server_lib.h
@@ -729,6 +729,16 @@ GNUNET_SERVER_notification_context_get_size (struct GNUNET_SERVER_NotificationCo
/**
+ * Create a message queue for a server's client.
+ *
+ * @param client the client
+ * @return the message queue
+ */
+struct GNUNET_MQ_Handle *
+GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
+
+
+/**
* Handle to a message stream tokenizer.
*/
struct GNUNET_SERVER_MessageStreamTokenizer;
diff --git a/src/set/set_api.c b/src/set/set_api.c
index 794ae57b77..343b5f8812 100644
--- a/src/set/set_api.c
+++ b/src/set/set_api.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2012-2014 GNUnet e.V.
+ 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
@@ -243,7 +243,7 @@ struct GNUNET_SET_ListenHandle
static struct GNUNET_SET_Handle *
create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
enum GNUNET_SET_OperationType op,
- uint32_t *cookie);
+ const uint32_t *cookie);
/**
@@ -251,21 +251,17 @@ create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
* iterator and sends an acknowledgement to the service.
*
* @param cls the `struct GNUNET_SET_Handle *`
- * @param mh the message
+ * @param msg the message
*/
static void
handle_copy_lazy (void *cls,
- const struct GNUNET_MessageHeader *mh)
+ const struct GNUNET_SET_CopyLazyResponseMessage *msg)
{
- struct GNUNET_SET_CopyLazyResponseMessage *msg;
struct GNUNET_SET_Handle *set = cls;
struct SetCopyRequest *req;
struct GNUNET_SET_Handle *new_set;
- msg = (struct GNUNET_SET_CopyLazyResponseMessage *) mh;
-
req = set->copy_req_head;
-
if (NULL == req)
{
/* Service sent us unsolicited lazy copy response */
@@ -275,53 +271,54 @@ handle_copy_lazy (void *cls,
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Handling response to lazy copy\n");
-
GNUNET_CONTAINER_DLL_remove (set->copy_req_head,
set->copy_req_tail,
req);
-
-
// We pass none as operation here, since it doesn't matter when
// cloning.
- new_set = create_internal (set->cfg, GNUNET_SET_OPERATION_NONE, &msg->cookie);
-
+ new_set = create_internal (set->cfg,
+ GNUNET_SET_OPERATION_NONE,
+ &msg->cookie);
req->cb (req->cls, new_set);
-
GNUNET_free (req);
}
/**
+ * Check that the given @a msg is well-formed.
+ *
+ * @param cls closure
+ * @param msg message to check
+ * @return #GNUNET_OK if message is well-formed
+ */
+static int
+check_iter_element (void *cls,
+ const struct GNUNET_SET_IterResponseMessage *msg)
+{
+ /* minimum size was already checked, everything else is OK! */
+ return GNUNET_OK;
+}
+
+
+/**
* Handle element for iteration over the set. Notifies the
* iterator and sends an acknowledgement to the service.
*
* @param cls the `struct GNUNET_SET_Handle *`
* @param mh the message
*/
-static void
-handle_iter_element (void *cls,
- const struct GNUNET_MessageHeader *mh)
+ static void
+ handle_iter_element (void *cls,
+ const struct GNUNET_SET_IterResponseMessage *msg)
{
struct GNUNET_SET_Handle *set = cls;
GNUNET_SET_ElementIterator iter = set->iterator;
- struct GNUNET_SET_Element element;
- const struct GNUNET_SET_IterResponseMessage *msg;
+ struct GNUNET_SET_Element element;
struct GNUNET_SET_IterAckMessage *ack_msg;
struct GNUNET_MQ_Envelope *ev;
uint16_t msize;
- msize = ntohs (mh->size);
- if (msize < sizeof (sizeof (struct GNUNET_SET_IterResponseMessage)))
- {
- /* message malformed */
- GNUNET_break (0);
- set->iterator = NULL;
- set->iteration_id++;
- iter (set->iterator_cls,
- NULL);
- iter = NULL;
- }
- msg = (const struct GNUNET_SET_IterResponseMessage *) mh;
+ msize = ntohs (msg->header.size);
if (set->iteration_id != ntohs (msg->iteration_id))
{
/* element from a previous iteration, skip! */
@@ -366,6 +363,22 @@ handle_iter_done (void *cls,
/**
+ * Check that the given @a msg is well-formed.
+ *
+ * @param cls closure
+ * @param msg message to check
+ * @return #GNUNET_OK if message is well-formed
+ */
+static int
+check_result (void *cls,
+ const struct GNUNET_SET_ResultMessage *msg)
+{
+ /* minimum size was already checked, everything else is OK! */
+ return GNUNET_OK;
+}
+
+
+/**
* Handle result message for a set operation.
*
* @param cls the set
@@ -373,15 +386,13 @@ handle_iter_done (void *cls,
*/
static void
handle_result (void *cls,
- const struct GNUNET_MessageHeader *mh)
+ const struct GNUNET_SET_ResultMessage *msg)
{
struct GNUNET_SET_Handle *set = cls;
- const struct GNUNET_SET_ResultMessage *msg;
struct GNUNET_SET_OperationHandle *oh;
struct GNUNET_SET_Element e;
enum GNUNET_SET_Status result_status;
- msg = (const struct GNUNET_SET_ResultMessage *) mh;
GNUNET_assert (NULL != set->mq);
result_status = ntohs (msg->result_status);
LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -442,7 +453,7 @@ do_element:
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Treating result as element\n");
e.data = &msg[1];
- e.size = ntohs (mh->size) - sizeof (struct GNUNET_SET_ResultMessage);
+ e.size = ntohs (msg->header.size) - sizeof (struct GNUNET_SET_ResultMessage);
e.element_type = ntohs (msg->element_type);
if (NULL != oh->result_cb)
oh->result_cb (oh->result_cls,
@@ -522,7 +533,8 @@ handle_client_set_error (void *cls,
enum GNUNET_MQ_Error error)
{
struct GNUNET_SET_Handle *set = cls;
-
+ GNUNET_SET_ElementIterator iter = set->iterator;
+
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Handling client set error %d\n",
error);
@@ -534,6 +546,11 @@ handle_client_set_error (void *cls,
GNUNET_SET_STATUS_FAILURE);
set_operation_destroy (set->ops_head);
}
+ set->iterator = NULL;
+ set->iteration_id++;
+ if (NULL != iter)
+ iter (set->iterator_cls,
+ NULL);
set->invalid = GNUNET_YES;
if (GNUNET_YES == set->destroy_requested)
{
@@ -547,31 +564,34 @@ handle_client_set_error (void *cls,
static struct GNUNET_SET_Handle *
create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
enum GNUNET_SET_OperationType op,
- uint32_t *cookie)
+ const uint32_t *cookie)
{
- static const struct GNUNET_MQ_MessageHandler mq_handlers[] = {
- { &handle_result,
- GNUNET_MESSAGE_TYPE_SET_RESULT,
- 0 },
- { &handle_iter_element,
- GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT,
- 0 },
- { &handle_iter_done,
- GNUNET_MESSAGE_TYPE_SET_ITER_DONE,
- sizeof (struct GNUNET_MessageHeader) },
- { &handle_copy_lazy,
- GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE,
- sizeof (struct GNUNET_SET_CopyLazyResponseMessage) },
- GNUNET_MQ_HANDLERS_END
+ GNUNET_MQ_hd_var_size (result,
+ GNUNET_MESSAGE_TYPE_SET_RESULT,
+ struct GNUNET_SET_ResultMessage);
+ GNUNET_MQ_hd_var_size (iter_element,
+ GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT,
+ struct GNUNET_SET_IterResponseMessage);
+ GNUNET_MQ_hd_fixed_size (iter_done,
+ GNUNET_MESSAGE_TYPE_SET_ITER_DONE,
+ struct GNUNET_MessageHeader);
+ GNUNET_MQ_hd_fixed_size (copy_lazy,
+ GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE,
+ struct GNUNET_SET_CopyLazyResponseMessage);
+ struct GNUNET_SET_Handle *set = GNUNET_new (struct GNUNET_SET_Handle);
+ struct GNUNET_MQ_MessageHandler mq_handlers[] = {
+ make_result_handler (set),
+ make_iter_element_handler (set),
+ make_it