diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ats/ats_api_scheduling.c | 35 | ||||
-rw-r--r-- | src/conversation/conversation_api.c | 88 | ||||
-rw-r--r-- | src/include/gnunet_client_lib.h | 59 | ||||
-rw-r--r-- | src/include/gnunet_mq_lib.h | 235 | ||||
-rw-r--r-- | src/include/gnunet_server_lib.h | 10 | ||||
-rw-r--r-- | src/set/set_api.c | 195 | ||||
-rw-r--r-- | src/util/mq.c | 107 | ||||
-rw-r--r-- | src/util/perf_crypto_asymmetric.c | 2 |
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 |