From 377e7340cce5136867734fb19e89a5fc51ac0c99 Mon Sep 17 00:00:00 2001 From: Gabor X Toth <*@tg-x.net> Date: Fri, 15 Jan 2016 22:12:29 +0000 Subject: social: set/clear msg proc flags --- src/include/gnunet_protocols.h | 7 +- src/include/gnunet_psyc_slicer.h | 73 +++++-- src/include/gnunet_social_service.h | 28 +++ src/psycutil/psyc_slicer.c | 101 ++++++++-- src/social/gnunet-service-social.c | 379 ++++++++++++++++++++++++++++-------- src/social/social.h | 13 +- src/social/social_api.c | 118 ++++++----- 7 files changed, 556 insertions(+), 163 deletions(-) diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 0251c57fe..7c63f60a3 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -2646,8 +2646,11 @@ extern "C" /** S->C: notify about an existing place */ #define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE 854 -/** S->C: */ -#define GNUNET_MESSAGE_TYPE_SOCIAL_HOST_RELAY 855 +/** C->S: set message processing flags */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET 860 + +/** C->S: clear message processing flags */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR 860 /******************************************************************************* * X-VINE DHT messages diff --git a/src/include/gnunet_psyc_slicer.h b/src/include/gnunet_psyc_slicer.h index 1851a6002..077c0c5bd 100644 --- a/src/include/gnunet_psyc_slicer.h +++ b/src/include/gnunet_psyc_slicer.h @@ -250,9 +250,9 @@ GNUNET_PSYC_slicer_method_remove (struct GNUNET_PSYC_Slicer *slicer, */ void GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer, - const char *object_filter, - GNUNET_PSYC_ModifierCallback modifier_cb, - void *cls); + const char *object_filter, + GNUNET_PSYC_ModifierCallback modifier_cb, + void *cls); /** @@ -270,30 +270,75 @@ GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer, */ int GNUNET_PSYC_slicer_modifier_remove (struct GNUNET_PSYC_Slicer *slicer, - const char *object_filter, - GNUNET_PSYC_ModifierCallback modifier_cb); + const char *object_filter, + GNUNET_PSYC_ModifierCallback modifier_cb); + + +/** + * Process an incoming message and call matching handlers. + * + * @param slicer + * The slicer to use. + * @param msg + * The message as it arrived from the network. + */ +void +GNUNET_PSYC_slicer_message (struct GNUNET_PSYC_Slicer *slicer, + const struct GNUNET_PSYC_MessageHeader *msg); /** * Process an incoming message part and call matching handlers. * - * @param cls - * Closure. + * @param slicer + * The slicer to use. * @param message_id * ID of the message. * @param flags * Flags for the message. * @see enum GNUNET_PSYC_MessageFlags + * @param fragment offset + * Fragment offset of the message. * @param msg - * The message part. as it arrived from the network. + * The message part as it arrived from the network. + */ +void +GNUNET_PSYC_slicer_message_part (struct GNUNET_PSYC_Slicer *slicer, + const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key, + uint64_t message_id, + uint32_t flags, + uint64_t fragment_offset, + const struct GNUNET_MessageHeader *msg); + + +/** + * Remove all registered method handlers. + * + * @param slicer + * Slicer to clear. + */ +void +GNUNET_PSYC_slicer_method_clear (struct GNUNET_PSYC_Slicer *slicer); + + +/** + * Remove all registered modifier handlers. + * + * @param slicer + * Slicer to clear. + */ +void +GNUNET_PSYC_slicer_modifier_clear (struct GNUNET_PSYC_Slicer *slicer); + + +/** + * Remove all registered method & modifier handlers. + * + * @param slicer + * Slicer to clear. */ void -GNUNET_PSYC_slicer_message (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key, - uint64_t message_id, - uint32_t flags, - uint64_t fragment_offset, - const struct GNUNET_MessageHeader *msg); +GNUNET_PSYC_slicer_clear (struct GNUNET_PSYC_Slicer *slicer); /** diff --git a/src/include/gnunet_social_service.h b/src/include/gnunet_social_service.h index 4ad6036a9..75038407b 100644 --- a/src/include/gnunet_social_service.h +++ b/src/include/gnunet_social_service.h @@ -232,6 +232,12 @@ extern "C" */ #define GNUNET_SOCIAL_APP_MAX_ID_SIZE 256 +enum GNUNET_SOCIAL_MsgProcFlags { + GNUNET_SOCIAL_MSG_PROC_NONE = 0, + GNUNET_SOCIAL_MSG_PROC_RELAY = 1, + GNUNET_SOCIAL_MSG_PROC_SAVE= 2, +}; + /** * Handle for an application. */ @@ -1062,6 +1068,28 @@ GNUNET_SOCIAL_guest_get_place (struct GNUNET_SOCIAL_Guest *guest); struct GNUNET_SOCIAL_HistoryRequest; +/** + * Set message processing @a flags for a @a method_prefix. + * + * @param plc + * Place. + * @param method_prefix + * Method prefix @a flags apply to. + * @param flags + * The flags that apply to a matching @a method_prefix. + */ +void +GNUNET_SOCIAL_place_msg_proc_set (struct GNUNET_SOCIAL_Place *plc, + const char *method_prefix, + enum GNUNET_SOCIAL_MsgProcFlags flags); + +/** + * Clear all message processing flags previously set for this place. + */ +void +GNUNET_SOCIAL_place_msg_proc_clear (struct GNUNET_SOCIAL_Place *plc); + + /** * Learn about the history of a place. * diff --git a/src/psycutil/psyc_slicer.c b/src/psycutil/psyc_slicer.c index fe9912416..e372d3ae2 100644 --- a/src/psycutil/psyc_slicer.c +++ b/src/psycutil/psyc_slicer.c @@ -49,6 +49,11 @@ struct GNUNET_PSYC_Slicer */ struct GNUNET_CONTAINER_MultiHashMap *modifier_handlers; + /** + * Receive handle for incoming messages. + */ + struct GNUNET_PSYC_ReceiveHandle *recv; + /** * Currently being processed message part. */ @@ -151,7 +156,7 @@ struct SlicerModifierRemoveClosure /** * Call a method handler for an incoming message part. */ -int +static int slicer_method_handler_notify (void *cls, const struct GNUNET_HashCode *key, void *value) { @@ -229,7 +234,7 @@ slicer_method_handler_notify (void *cls, const struct GNUNET_HashCode *key, /** * Call a method handler for an incoming message part. */ -int +static int slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key, void *value) { @@ -243,6 +248,22 @@ slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key, } +/** + * Process an incoming message and call matching handlers. + * + * @param slicer + * The slicer to use. + * @param msg + * The message as it arrived from the network. + */ +void +GNUNET_PSYC_slicer_message (struct GNUNET_PSYC_Slicer *slicer, + const struct GNUNET_PSYC_MessageHeader *msg) +{ + GNUNET_PSYC_receive_message (slicer->recv, msg); +} + + /** * Process an incoming message part and call matching handlers. * @@ -257,11 +278,13 @@ slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key, * The message part. as it arrived from the network. */ void -GNUNET_PSYC_slicer_message (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key, - uint64_t message_id, uint32_t flags, uint64_t fragment_offset, - const struct GNUNET_MessageHeader *msg) +GNUNET_PSYC_slicer_message_part (struct GNUNET_PSYC_Slicer *slicer, + const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key, + uint64_t message_id, + uint32_t flags, + uint64_t fragment_offset, + const struct GNUNET_MessageHeader *msg) { - struct GNUNET_PSYC_Slicer *slicer = cls; slicer->nym_pub_key = *slave_pub_key; uint16_t ptype = ntohs (msg->type); @@ -381,6 +404,10 @@ GNUNET_PSYC_slicer_create (void) struct GNUNET_PSYC_Slicer *slicer = GNUNET_malloc (sizeof (*slicer)); slicer->method_handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); slicer->modifier_handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); + slicer->recv = GNUNET_PSYC_receive_create (NULL, + (GNUNET_PSYC_MessagePartCallback) + GNUNET_PSYC_slicer_message_part, + slicer); return slicer; } @@ -430,7 +457,7 @@ GNUNET_PSYC_slicer_method_add (struct GNUNET_PSYC_Slicer *slicer, } -int +static int slicer_method_remove (void *cls, const struct GNUNET_HashCode *key, void *value) { struct SlicerMethodRemoveClosure *rm_cls = cls; @@ -531,7 +558,7 @@ GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer, } -int +static int slicer_modifier_remove (void *cls, const struct GNUNET_HashCode *key, void *value) { struct SlicerModifierRemoveClosure *rm_cls = cls; @@ -585,7 +612,7 @@ GNUNET_PSYC_slicer_modifier_remove (struct GNUNET_PSYC_Slicer *slicer, } -int +static int slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value) { struct SlicerMethodCallbacks *cbs = value; @@ -594,6 +621,57 @@ slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value) } +static int +slicer_modifier_free (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct SlicerModifierCallbacks *cbs = value; + GNUNET_free (cbs); + return GNUNET_YES; +} + + +/** + * Remove all registered method handlers. + * + * @param slicer + * Slicer to clear. + */ +void +GNUNET_PSYC_slicer_method_clear (struct GNUNET_PSYC_Slicer *slicer) +{ + GNUNET_CONTAINER_multihashmap_iterate (slicer->method_handlers, + slicer_method_free, NULL); +} + + +/** + * Remove all registered modifier handlers. + * + * @param slicer + * Slicer to clear. + */ +void +GNUNET_PSYC_slicer_modifier_clear (struct GNUNET_PSYC_Slicer *slicer) +{ + GNUNET_CONTAINER_multihashmap_iterate (slicer->modifier_handlers, + slicer_modifier_free, NULL); +} + + +/** + * Remove all registered method & modifier handlers. + * + * @param slicer + * Slicer to clear. + */ +void +GNUNET_PSYC_slicer_clear (struct GNUNET_PSYC_Slicer *slicer) +{ + GNUNET_PSYC_slicer_method_clear (slicer); + GNUNET_PSYC_slicer_modifier_clear (slicer); +} + + /** * Destroy a given try-and-slice instance. * @@ -603,8 +681,9 @@ slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value) void GNUNET_PSYC_slicer_destroy (struct GNUNET_PSYC_Slicer *slicer) { - GNUNET_CONTAINER_multihashmap_iterate (slicer->method_handlers, - slicer_method_free, NULL); + GNUNET_PSYC_slicer_clear (slicer); GNUNET_CONTAINER_multihashmap_destroy (slicer->method_handlers); + GNUNET_CONTAINER_multihashmap_destroy (slicer->modifier_handlers); + GNUNET_PSYC_receive_destroy (slicer->recv); GNUNET_free (slicer); } diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c index d4dfe9b0f..f3eacd6f9 100644 --- a/src/social/gnunet-service-social.c +++ b/src/social/gnunet-service-social.c @@ -229,10 +229,10 @@ struct Place */ struct GNUNET_HashCode ego_pub_hash; - uint64_t file_message_id; - uint64_t file_fragment_offset; - uint64_t file_size; - uint64_t file_offset; + /** + * Slicer for processing incoming messages. + */ + struct GNUNET_PSYC_Slicer *slicer; /** * Last message ID received for the place. @@ -240,6 +240,16 @@ struct Place */ uint64_t max_message_id; + /** + * Offset where the file is currently being written. + */ + uint64_t file_offset; + + /** + * Whether or not to save the file (#GNUNET_YES or #GNUNET_NO) + */ + uint8_t file_save; + /** * Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)? */ @@ -509,6 +519,8 @@ cleanup_place (struct Place *plc) (GNUNET_YES == plc->is_host) ? cleanup_host ((struct Host *) plc) : cleanup_guest ((struct Guest *) plc); + + GNUNET_PSYC_slicer_destroy (plc->slicer); GNUNET_free (plc); } @@ -728,34 +740,132 @@ psyc_recv_join_dcsn (void *cls, place_send_msg (&gst->plc, &dcsn->header); } + /** - * Save _file data to disk. + * Called when a PSYC master or slave receives a message. */ -void -psyc_recv_file (struct Place *plc, const struct GNUNET_PSYC_MessageHeader *msg, - uint32_t flags, uint64_t message_id, uint64_t fragment_offset, - const char *method_name, struct GNUNET_PSYC_Environment *env, - const void *data, uint16_t data_size) +static void +psyc_recv_message (void *cls, + uint64_t message_id, + uint32_t flags, + const struct GNUNET_PSYC_MessageHeader *msg) +{ + struct Place *plc = cls; + + char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&msg->slave_pub_key); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%p Received PSYC message of size %u from %s.\n", + plc, ntohs (msg->header.size), str); + GNUNET_free (str); + + GNUNET_PSYC_slicer_message (plc->slicer, msg); + + place_send_msg (plc, &msg->header); +} + + +static void +place_recv_relay_method (void *cls, + const struct GNUNET_PSYC_MessageMethod *meth, + uint64_t message_id, + uint32_t flags, + const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key, + const char *method_name) +{ + struct Host *hst = cls; + struct Place *plc = &hst->plc; + + // FIXME: relay message +} + + +static void +place_recv_relay_modifier (void *cls, + const struct GNUNET_MessageHeader *msg, + uint64_t message_id, + enum GNUNET_PSYC_Operator oper, + const char *name, + const void *value, + uint16_t value_size, + uint16_t full_value_size) { - if (plc->file_message_id != message_id) - { - if (0 != fragment_offset) - { - /* unexpected message ID */ - GNUNET_break (0); - return; - } - /* new file */ - plc->file_offset = 0; +} + + +static void +place_recv_relay_eom (void *cls, + const struct GNUNET_MessageHeader *msg, + uint64_t message_id, + uint8_t cancelled) +{ + +} + + +static void +place_recv_relay_data (void *cls, + const struct GNUNET_MessageHeader *msg, + uint64_t message_id, + uint64_t data_offset, + const void *data, + uint16_t data_size) +{ + +} + + +static void +place_recv_save_method (void *cls, + const struct GNUNET_PSYC_MessageMethod *meth, + uint64_t message_id, + uint32_t flags, + const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key, + const char *method_name) +{ + struct Place *plc = cls; + plc->file_offset = 0; + plc->file_save = GNUNET_NO; + + struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii; + memcpy (&place_pub_hash_ascii.encoding, + GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii)); + + char *filename = NULL; + GNUNET_asprintf (&filename, "%s%c%s%c%s%c%.part" PRIu64, + dir_social, DIR_SEPARATOR, + "files", DIR_SEPARATOR, + place_pub_hash_ascii.encoding, DIR_SEPARATOR, + message_id); + + /* save if does not already exist */ + if (GNUNET_NO == GNUNET_DISK_file_test (filename)) + { + plc->file_save = GNUNET_YES; } + GNUNET_free (filename); +} + + +static void +place_recv_save_data (void *cls, + const struct GNUNET_MessageHeader *msg, + uint64_t message_id, + uint64_t data_offset, + const void *data, + uint16_t data_size) +{ + struct Place *plc = cls; + if (GNUNET_YES != plc->file_save) + return; + struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii; memcpy (&place_pub_hash_ascii.encoding, GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii)); char *filename = NULL; - GNUNET_asprintf (&filename, "%s%c%s%c%s%c%" PRIu64, + GNUNET_asprintf (&filename, "%s%c%s%c%s%c%.part" PRIu64, dir_social, DIR_SEPARATOR, "files", DIR_SEPARATOR, place_pub_hash_ascii.encoding, DIR_SEPARATOR, @@ -774,50 +884,38 @@ psyc_recv_file (struct Place *plc, const struct GNUNET_PSYC_MessageHeader *msg, } -/** - * Called when a PSYC master or slave receives a message. - */ static void -psyc_recv_message (void *cls, - uint64_t message_id, - uint32_t flags, - const struct GNUNET_PSYC_MessageHeader *msg) +place_recv_save_eom (void *cls, + const struct GNUNET_MessageHeader *msg, + uint64_t message_id, + uint8_t cancelled) { struct Place *plc = cls; + if (GNUNET_YES != plc->file_save) + return; - char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&msg->slave_key); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "%p Received PSYC message of size %u from %s.\n", - plc, ntohs (msg->header.size), str); - GNUNET_free (str); + struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii; + memcpy (&place_pub_hash_ascii.encoding, + GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii)); - /* process message */ - /* FIXME: use slicer */ - const char *method_name = NULL; - struct GNUNET_PSYC_Environment *env = GNUNET_PSYC_env_create (); - const void *data = NULL; - uint16_t data_size = 0; + char *fn_part = NULL; + GNUNET_asprintf (&fn_part, "%s%c%s%c%s%c%.part" PRIu64, + dir_social, DIR_SEPARATOR, + "files", DIR_SEPARATOR, + place_pub_hash_ascii.encoding, DIR_SEPARATOR, + message_id); - if (GNUNET_SYSERR == GNUNET_PSYC_message_parse (msg, &method_name, env, &data, &data_size)) - { - GNUNET_break (0); - } - else - { - char *method_found = strstr (method_name, "_file"); - if (method_name == method_found) - { - method_found += strlen ("_file"); - if (('\0' == *method_found) || ('_' == *method_found)) - { - psyc_recv_file (plc, msg, flags, message_id, GNUNET_ntohll (msg->fragment_offset), - method_name, env, data, data_size); - } - } - } - GNUNET_PSYC_env_destroy (env); + char *fn = NULL; + GNUNET_asprintf (&fn, "%s%c%s%c%s%c%" PRIu64, + dir_social, DIR_SEPARATOR, + "files", DIR_SEPARATOR, + place_pub_hash_ascii.encoding, DIR_SEPARATOR, + message_id); - place_send_msg (plc, &msg->header); + rename (fn_part, fn); + + GNUNET_free (fn); + GNUNET_free (fn_part); } @@ -1118,6 +1216,7 @@ host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst) plc->is_host = GNUNET_YES; plc->pub_key = hreq->place_pub_key; plc->pub_key_hash = place_pub_hash; + plc->slicer = GNUNET_PSYC_slicer_create (); GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); @@ -1125,7 +1224,7 @@ host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst) &psyc_master_started, &psyc_recv_join_request, &psyc_recv_message, NULL, hst); - hst->plc.channel = GNUNET_PSYC_master_get_channel (hst->master); + plc->channel = GNUNET_PSYC_master_get_channel (hst->master); ret = GNUNET_YES; } @@ -1135,6 +1234,115 @@ host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst) } +const struct MsgProcRequest * +relay_req_parse (const struct GNUNET_MessageHeader *msg, + uint32_t *flags, + const char **method_prefix, + struct GNUNET_HashCode *method_hash) +{ + const struct MsgProcRequest *mpreq = (const struct MsgProcRequest *) msg; + uint8_t method_size = ntohs (mpreq->header.size) - sizeof (*mpreq); + uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &mpreq[1], + method_size, 1, method_prefix); + + if (0 == offset || offset != method_size || *method_prefix == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "offset = %u, method_size = %u, method_name = %s\n", + offset, method_size, *method_prefix); + return NULL; + } + + GNUNET_CRYPTO_hash (*method_prefix, method_size, method_hash); + *flags = ntohl (mpreq->flags); + return mpreq; +} + + +/** + * Handle a client setting message proccesing flags for a method prefix. + */ +static void +client_recv_msg_proc_set (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *msg) +{ + struct Client * + ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); + GNUNET_assert (NULL != ctx); + struct Place *plc = ctx->plc; + + const char *method_prefix = NULL; + uint32_t flags = 0; + struct GNUNET_HashCode method_hash; + const struct MsgProcRequest * + mpreq = relay_req_parse (msg, &flags, &method_prefix, &method_hash); + + if (NULL == mpreq) { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + + GNUNET_PSYC_slicer_method_remove (plc->slicer, method_prefix, + place_recv_relay_method, + place_recv_relay_modifier, + place_recv_relay_data, + place_recv_relay_eom); + GNUNET_PSYC_slicer_method_remove (plc->slicer, method_prefix, + place_recv_save_method, + NULL, + place_recv_save_data, + place_recv_save_eom); + + if (flags & GNUNET_SOCIAL_MSG_PROC_RELAY) + { + GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix, + place_recv_relay_method, + place_recv_relay_modifier, + place_recv_relay_data, + place_recv_relay_eom, + plc); + } + if (flags & GNUNET_SOCIAL_MSG_PROC_SAVE) + { + GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix, + place_recv_save_method, + NULL, + place_recv_save_data, + place_recv_save_eom, + plc); + } + + /** @todo Save flags to be able to resume relaying/saving after restart */ + + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + +/** + * Handle a connecting client requesting to clear all relay rules. + */ +static void +client_recv_msg_proc_clear (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *msg) +{ + struct Client * + ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); + GNUNET_assert (NULL != ctx); + struct Place *plc = ctx->plc; + if (GNUNET_YES != plc->is_host) { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + struct Host *hst = (struct Host *) plc; + + GNUNET_PSYC_slicer_clear (plc->slicer); + + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + /** * Handle a connecting client entering a place as host. */ @@ -1320,6 +1528,7 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst) plc->ego_pub_key = ego_pub_key; plc->ego_pub_hash = ego_pub_hash; plc->ego_key = ego->key; + plc->slicer = GNUNET_PSYC_slicer_create (); if (NULL == plc_gst) { @@ -1339,7 +1548,7 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst) &psyc_slave_connected, &psyc_recv_join_dcsn, gst, join_msg); - gst->plc.channel = GNUNET_PSYC_slave_get_channel (gst->slave); + plc->channel = GNUNET_PSYC_slave_get_channel (gst->slave); ret = GNUNET_YES; } @@ -1805,7 +2014,11 @@ client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); GNUNET_assert (NULL != ctx); struct Place *plc = ctx->plc; - GNUNET_assert (GNUNET_YES == plc->is_host); + if (GNUNET_YES != plc->is_host) { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } struct Host *hst = (struct Host *) plc; struct GNUNET_PSYC_JoinDecisionMessage * @@ -1817,20 +2030,20 @@ client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, ? (struct GNUNET_PSYC_Message *) &dcsn[1] : NULL; - struct GNUNET_HashCode slave_key_hash; - GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key), - &slave_key_hash); + struct GNUNET_HashCode slave_pub_hash; + GNUNET_CRYPTO_hash (&dcsn->slave_pub_key, sizeof (dcsn->slave_pub_key), + &slave_pub_hash); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Got join decision (%d) from client for place %s..\n", hst, jcls.is_admitted, GNUNET_h2s (&plc->pub_key_hash)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p ..and slave %s.\n", - hst, GNUNET_h2s (&slave_key_hash)); + hst, GNUNET_h2s (&slave_pub_hash)); - GNUNET_CONTAINER_multihashmap_get_multiple (hst->join_reqs, &slave_key_hash, + GNUNET_CONTAINER_multihashmap_get_multiple (hst->join_reqs, &slave_pub_hash, &psyc_send_join_decision, &jcls); - GNUNET_CONTAINER_multihashmap_remove_all (hst->join_reqs, &slave_key_hash); + GNUNET_CONTAINER_multihashmap_remove_all (hst->join_reqs, &slave_pub_hash); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -2832,45 +3045,51 @@ client_recv_zone_add_nym (void *cls, struct GNUNET_SERVER_Client *client, static const struct GNUNET_SERVER_MessageHandler handlers[] = { - { &client_recv_host_enter, NULL, + { client_recv_host_enter, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER, 0 }, - { &client_recv_guest_enter, NULL, + { client_recv_guest_enter, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER, 0 }, - { &client_recv_guest_enter_by_name, NULL, + { client_recv_guest_enter_by_name, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_BY_NAME, 0 }, - { &client_recv_join_decision, NULL, + { client_recv_join_decision, NULL, GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 }, - { &client_recv_psyc_message, NULL, + { client_recv_psyc_message, NULL, GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 }, - { &client_recv_history_replay, NULL, + { client_recv_history_replay, NULL, GNUNET_MESSAGE_TYPE_PSYC_HISTORY_REPLAY, 0 }, - { &client_recv_state_get, NULL, + { client_recv_state_get, NULL, GNUNET_MESSAGE_TYPE_PSYC_STATE_GET, 0 }, - { &client_recv_state_get, NULL, + { client_recv_state_get, NULL, GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 }, - { &client_recv_zone_add_place, NULL, + { client_recv_zone_add_place, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_PLACE, 0 }, - { &client_recv_zone_add_nym, NULL, + { client_recv_zone_add_nym, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_NYM, 0 }, - { &client_recv_app_connect, NULL, + { client_recv_app_connect, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT, 0 }, - { &client_recv_app_detach, NULL, + { client_recv_app_detach, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH, 0 }, - { &client_recv_place_leave, NULL, + { client_recv_place_leave, NULL, GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE, 0 }, + { client_recv_msg_proc_set, NULL, + GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET, 0 }, + + { client_recv_msg_proc_clear, NULL, + GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR, 0 }, + { NULL, NULL, 0, 0 } }; diff --git a/src/social/social.h b/src/social/social.h index 0980cbf5c..d24515309 100644 --- a/src/social/social.h +++ b/src/social/social.h @@ -80,16 +80,19 @@ struct AppDetachRequest }; -struct HostRelayRequest +struct MsgProcRequest { /** - * Types: - * - GNUNET_MESSAGE_TYPE_SOCIAL_HOST_RELAY_START - * - GNUNET_MESSAGE_TYPE_SOCIAL_HOST_RELAY_STOP + * Type: GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET */ struct GNUNET_MessageHeader header; - /* Followed by char *method_name */ + /** + * @see enum GNUNET_SOCIAL_MsgProcFlags + */ + uint32_t flags; + + /* Followed by char *method_prefix */ }; diff --git a/src/social/social_api.c b/src/social/social_api.c index 3404160a9..a8433ee24 100644 --- a/src/social/social_api.c +++ b/src/social/social_api.c @@ -149,12 +149,7 @@ struct GNUNET_SOCIAL_Place struct GNUNET_PSYC_TransmitHandle *tmit; /** - * Receipt handle. - */ - struct GNUNET_PSYC_ReceiveHandle *recv; - - /** - * Slicer for processing incoming methods. + * Slicer for processing incoming messages. */ struct GNUNET_PSYC_Slicer *slicer; @@ -204,12 +199,7 @@ struct GNUNET_SOCIAL_Host struct GNUNET_SOCIAL_Place plc; /** - * Receipt handle. - */ - struct GNUNET_PSYC_ReceiveHandle *recv; - - /** - * Slicer for processing incoming methods. + * Slicer for processing incoming messages from guests. */ struct GNUNET_PSYC_Slicer *slicer; @@ -236,16 +226,6 @@ struct GNUNET_SOCIAL_Guest { struct GNUNET_SOCIAL_Place plc; - /** - * Receipt handle. - */ - struct GNUNET_PSYC_ReceiveHandle *recv; - - /** - * Slicer for processing incoming methods. - */ - struct GNUNET_PSYC_Slicer *slicer; - GNUNET_SOCIAL_GuestEnterCallback enter_cb; GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb; @@ -298,9 +278,9 @@ struct GNUNET_SOCIAL_HistoryRequest uint64_t op_id; /** - * Message handler. + * Slicer for processing incoming messages. */ - struct GNUNET_PSYC_ReceiveHandle *recv; + struct GNUNET_PSYC_Slicer *slicer; /** * Function to call when the operation finished. @@ -519,6 +499,7 @@ app_send_connect_msg (struct GNUNET_SOCIAL_App *app) struct GNUNET_MessageHeader * cmsg = GNUNET_malloc (cmsg_size); memcpy (cmsg, app->connect_msg, cmsg_size); GNUNET_CLIENT_MANAGER_transmit_now (app->client, cmsg); + GNUNET_free (cmsg); } @@ -545,6 +526,7 @@ place_send_connect_msg (struct GNUNET_SOCIAL_Place *plc) struct GNUNET_MessageHeader * cmsg = GNUNET_malloc (cmsg_size); memcpy (cmsg, plc->connect_msg, cmsg_size); GNUNET_CLIENT_MANAGER_transmit_now (plc->client, cmsg); + GNUNET_free (cmsg); } @@ -625,7 +607,6 @@ op_recv_history_result (void *cls, int64_t result, if (NULL != hist->result_cb) hist->result_cb (hist->cls, result, err_msg, err_msg_size); - GNUNET_PSYC_receive_destroy (hist->recv); GNUNET_free (hist); } @@ -684,8 +665,8 @@ place_recv_history_result (void *cls, return; } - GNUNET_PSYC_receive_message (hist->recv, - (const struct GNUNET_PSYC_MessageHeader *) pmsg); + GNUNET_PSYC_slicer_message (hist->slicer, + (const struct GNUNET_PSYC_MessageHeader *) pmsg); } @@ -781,7 +762,7 @@ place_recv_message (void *cls, { struct GNUNET_SOCIAL_Place * plc = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*plc)); - GNUNET_PSYC_receive_message (plc->recv, + GNUNET_PSYC_slicer_message (plc->slicer, (const struct GNUNET_PSYC_MessageHeader *) msg); } @@ -793,10 +774,10 @@ host_recv_message (void *cls, { struct GNUNET_SOCIAL_Host * hst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (hst->plc)); - GNUNET_PSYC_receive_message (hst->recv, - (const struct GNUNET_PSYC_MessageHeader *) msg); - GNUNET_PSYC_receive_message (hst->plc.recv, - (const struct GNUNET_PSYC_MessageHeader *) msg); + GNUNET_PSYC_slicer_message (hst->slicer, + (const struct GNUNET_PSYC_MessageHeader *) msg); + GNUNET_PSYC_slicer_message (hst->plc.slicer, + (const struct GNUNET_PSYC_MessageHeader *) msg); } @@ -855,7 +836,7 @@ host_recv_enter_request (void *cls, &data, &data_size)) { GNUNET_break_op (0); - str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&req->slave_key); + str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&req->slave_pub_key); LOG (GNUNET_ERROR_TYPE_WARNING, "Ignoring invalid entry request from nym %s.\n", str); @@ -864,7 +845,7 @@ host_recv_enter_request (void *cls, } } - struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&req->slave_key); + struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&req->slave_pub_key); hst->answer_door_cb (hst->cb_cls, nym, method_name, env, data_size, data); } while (0); @@ -1098,8 +1079,6 @@ place_cleanup (struct GNUNET_SOCIAL_Place *plc) { if (NULL != plc->tmit) GNUNET_PSYC_transmit_destroy (plc->tmit); - if (NULL != plc->recv) - GNUNET_PSYC_receive_destroy (plc->recv); if (NULL != plc->connect_msg) GNUNET_free (plc->connect_msg); if (NULL != plc->disconnect_cb) @@ -1112,11 +1091,6 @@ host_cleanup (void *cls) { struct GNUNET_SOCIAL_Host *hst = cls; place_cleanup (&hst->plc); - if (NULL != hst->recv) - { - GNUNET_PSYC_receive_destroy (hst->recv); - hst->recv = NULL; - } if (NULL != hst->slicer) { GNUNET_PSYC_slicer_destroy (hst->slicer); @@ -1191,14 +1165,12 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_SOCIAL_App *app, GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc)); plc->tmit = GNUNET_PSYC_transmit_create (plc->client); - plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer); hst->slicer = GNUNET_PSYC_slicer_create (); GNUNET_PSYC_slicer_method_add (hst->slicer, "_notice_place_leave", host_recv_notice_place_leave_method, host_recv_notice_place_leave_modifier, NULL, host_recv_notice_place_leave_eom, hst); - hst->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, hst->slicer); uint16_t app_id_size = strlen (app->id) + 1; struct HostEnterRequest *hreq = GNUNET_malloc (sizeof (*hreq) + app_id_size); @@ -1263,14 +1235,12 @@ GNUNET_SOCIAL_host_enter_reconnect (struct GNUNET_SOCIAL_HostConnection *hconn, GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc)); plc->tmit = GNUNET_PSYC_transmit_create (plc->client); - plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer); hst->slicer = GNUNET_PSYC_slicer_create (); GNUNET_PSYC_slicer_method_add (hst->slicer, "_notice_place_leave", host_recv_notice_place_leave_method, host_recv_notice_place_leave_modifier, NULL, host_recv_notice_place_leave_eom, hst); - hst->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, hst->slicer); hreq->header.size = htons (sizeof (*hreq) + app_id_size); hreq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER); @@ -1325,12 +1295,13 @@ GNUNET_SOCIAL_host_entry_decision (struct GNUNET_SOCIAL_Host *hst, dcsn->header.size = htons (sizeof (*dcsn) + entry_resp_size); dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION); dcsn->is_admitted = htonl (is_admitted); - dcsn->slave_key = nym->pub_key; + dcsn->slave_pub_key = nym->pub_key; if (0 < entry_resp_size) memcpy (&dcsn[1], entry_resp, entry_resp_size); GNUNET_CLIENT_MANAGER_transmit (hst->plc.client, &dcsn->header); + GNUNET_free (dcsn); return GNUNET_OK; } @@ -1690,7 +1661,6 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_SOCIAL_App *app, GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); plc->tmit = GNUNET_PSYC_transmit_create (plc->client); - plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer); struct GuestEnterRequest * greq = guest_enter_request_create (app->id, &ego->pub_key, &plc->pub_key, @@ -1782,7 +1752,6 @@ GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_SOCIAL_App *app, GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); plc->tmit = GNUNET_PSYC_transmit_create (plc->client); - plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer); plc->connect_msg = &greq->header; place_send_connect_msg (plc); @@ -1842,7 +1811,6 @@ GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection *gconn GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); plc->tmit = GNUNET_PSYC_transmit_create (plc->client); - plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer); plc->connect_msg = &greq->header; place_send_connect_msg (plc); @@ -1994,6 +1962,52 @@ GNUNET_SOCIAL_place_get_key (struct GNUNET_SOCIAL_Place *plc) } +/** + * Set message processing @a flags for a @a method_prefix. + * + * @param plc + * Place. + * @param method_prefix + * Method prefix @a flags apply to. + * @param flags + * The flags that apply to a matching @a method_prefix. + */ +void +GNUNET_SOCIAL_place_msg_proc_set (struct GNUNET_SOCIAL_Place *plc, + const char *method_prefix, + enum GNUNET_SOCIAL_MsgProcFlags flags) +{ + GNUNET_assert (NULL != method_prefix); + struct MsgProcRequest *mpreq; + uint16_t method_size = strnlen (method_prefix, + GNUNET_SERVER_MAX_MESSAGE_SIZE + - sizeof (*mpreq)) + 1; + GNUNET_assert ('\0' == method_prefix[method_size - 1]); + mpreq = GNUNET_malloc (sizeof (*mpreq) + method_size); + + mpreq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET); + mpreq->header.size = htons (sizeof (*mpreq) + method_size); + mpreq->flags = htonl (flags); + memcpy (&mpreq[1], method_prefix, method_size); + + GNUNET_CLIENT_MANAGER_transmit (plc->client, &mpreq->header); + GNUNET_free (mpreq); +} + + +/** + * Clear all message processing flags previously set for this place. + */ +void +GNUNET_SOCIAL_place_msg_proc_clear (struct GNUNET_SOCIAL_Place *plc) +{ + struct GNUNET_MessageHeader req; + req.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR); + req.size = htons (sizeof (req)); + GNUNET_CLIENT_MANAGER_transmit (plc->client, &req); +} + + static struct GNUNET_SOCIAL_HistoryRequest * place_history_replay (struct GNUNET_SOCIAL_Place *plc, uint64_t start_message_id, @@ -2008,7 +2022,7 @@ place_history_replay (struct GNUNET_SOCIAL_Place *plc, struct GNUNET_PSYC_HistoryRequestMessage *req; struct GNUNET_SOCIAL_HistoryRequest *hist = GNUNET_malloc (sizeof (*hist)); hist->plc = plc; - hist->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, slicer); + hist->slicer = slicer; hist->result_cb = result_cb; hist->cls = cls; hist->op_id = GNUNET_CLIENT_MANAGER_op_add (plc->client, @@ -2030,6 +2044,7 @@ place_history_replay (struct GNUNET_SOCIAL_Place *plc, memcpy (&req[1], method_prefix, method_size); GNUNET_CLIENT_MANAGER_transmit (plc->client, &req->header); + GNUNET_free (req); return hist; } @@ -2118,7 +2133,6 @@ GNUNET_SOCIAL_place_history_replay_latest (struct GNUNET_SOCIAL_Place *plc, void GNUNET_SOCIAL_place_history_replay_cancel (struct GNUNET_SOCIAL_HistoryRequest *hist) { - GNUNET_PSYC_receive_destroy (hist->recv); GNUNET_CLIENT_MANAGER_op_cancel (hist->plc->client, hist->op_id); GNUNET_free (hist); } @@ -2152,6 +2166,7 @@ place_state_get (struct GNUNET_SOCIAL_Place *plc, memcpy (&req[1], name, name_size); GNUNET_CLIENT_MANAGER_transmit (plc->client, &req->header); + GNUNET_free (req); return look; } @@ -2314,6 +2329,7 @@ GNUNET_SOCIAL_zone_add_place (const struct GNUNET_SOCIAL_App *app, op_recv_zone_add_place_result, add_plc)); GNUNET_CLIENT_MANAGER_transmit_now (app->client, &preq->header); + GNUNET_free (preq); return GNUNET_OK; } -- cgit v1.2.3